当 operator new 没有能力为分配出我们所申请的 memory,会抛出一个 std::bad_alloc exception。某些老编译器则是返回 0 ,现代编译器仍然可以这样做:new (nothrow) Foo;

抛出 exception 之前会先(不止一次)调用一个可有 client 指定的 handler, 以下是 new handler 的形式和设定方法:

typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
  • 设计良好的 new_handler 只有两个选择:

    • 让更多的 memory 可用
    • 调用 abort()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;
}

输出[gcc version 7.5.0]

0x55ad89dd7e70
out of memory
Aborted (core dumped)

本例中 new handler 中如果没有调用 abort(), 执行后 cerr 会不断出现 "out of memory", 需强制中断。这样的表现是正确的,表示当 operator new 无法满足申请量时,会不断调用 new handler 直到得到足够 memory.

default、delete

default、delete 不仅适用于构造函数(拷贝构造、移动构造)和赋值函数(拷贝赋值、移动赋值)

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

实际测试:

#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
737 声望139 粉丝

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