C++内存管理7_new handler

Posted TianSong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++内存管理7_new handler相关的知识,希望对你有一定的参考价值。

当 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;
}

以上是关于C++内存管理7_new handler的主要内容,如果未能解决你的问题,请参考以下文章

定制new和delete

C++内存管理 && 读高质量C++/C编程指南第7章

C++内存管理基础篇

C++ 中的 new/delete 导致奇怪的内存泄漏

C++内存管理机制学习笔记:replacement new

C++内存管理机制学习笔记:Array new