When operator new is unable to allocate the memory we requested, it will throw a std::bad_alloc exception. Some old compilers return 0, but modern compilers can still do this: new (nothrow) Foo;

Before the exception is thrown, a handler that can be specified by the client is called (more than once). The following is the form and setting method of the new handler:

typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
  • There are only two options for a well-designed new_handler:

    • Make more memory available
    • Call abort() or exit()
void *operator_new(size_t size, const std::nothrow_t &_THROW0())
{
    // try to allocate size bytes
    void *p;
    while ((p = malloc(size)) == 0)
    {
        // buy more memory or return null pointer
        _TRY_BEGIN
            if (_callnew_h(size) == 0) break;
        _CATCH(std::bad_alloc) return 0;
        _CATCH_END
    }
    return (p);
}
#include <new>
#include <iostream>
#include <cassert>

using namespace std;

void onMoreMemory()
{
    cerr << "out of memory" << endl;
    abort();
}

int main()
{
    set_new_handler(onMoreMemory);

    int *p = new int[10000];
    assert(p);
    cout << p << endl;

    p = new int[100000000000000];
    assert(p);
    cout << p << endl;

    return 0;
}

Output [gcc version 7.5.0]

0x55ad89dd7e70
out of memory
Aborted (core dumped)

In this example, if abort() is not called in the new handler, cerr will continue to appear "out of memory" after execution, and it needs to be interrupted forcibly. This behavior is correct. It means that when operator new cannot meet the application amount, it will keep calling new handler until enough memory is obtained.

default、delete

Default and delete are not only applicable to constructors (copy construction, move construction) and assignment functions (copy assignment, move assignment)

class Foo {
public:
    Foo() = default;
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
    ~Foo() = default;
};

practical testing:

#include <iostream>

using namespace std;

class Foo {
public:
    long _x;
public:
    Foo(long x = 0) : _x(x)
    { }

    // static void *operator new(size_t size) = default;                   // error: only special member functions may be defaulted
    // static void operator delete(void *pdead, size_t size) = default;    // error: only special member functions may be defaulted
    static void *operator new[](size_t size) = delete;
    static void operator delete[](void *pdead, size_t size) = delete;
};

int main()
{
    // Foo *p1 = new Foo[10];  // error: call to deleted function 'operator new[]'
    // delete []  p1;          // error: attempt to use a deleted function

    return 0;
}

TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧