【C++內存管理】7_new handler

當 operator new 沒有能力爲分配出咱們所申請的 memory,會拋出一個 std::bad_alloc exception。某些老編譯器則是返回 0 ,現代編譯器仍然能夠這樣作:new (nothrow) Foo;ios

拋出 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]spa

0x55ad89dd7e70
out of memory
Aborted (core dumped)

本例中 new handler 中若是沒有調用 abort(), 執行後 cerr 會不斷出現 "out of memory", 需強制中斷。這樣的表現是正確的,表示當 operator new 沒法知足申請量時,會不斷調用 new handler 直到獲得足夠 memory.設計

default、delete

default、delete 不只適用於構造函數(拷貝構造、移動構造)和賦值函數(拷貝賦值、移動賦值)code

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

實際測試:ci

#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;
}
相關文章
相關標籤/搜索