关于c++:C内存管理7new-handler

6次阅读

共计 1676 个字符,预计需要花费 5 分钟才能阅读完成。

当 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;
}
正文完
 0