C++ - 了解new_handler的所作所为

1. 在使用operator new申请内存失败后,编译器并不是不做任何的努力直接抛出std::bad_alloc异常,在这之前,它会调用一个错误处理函数(new_handler)。


2. new_handler函数的处理方式策略:
(1)operator new会进行多次的内存分配尝试,这可能会使其下一次的内存分配尝试成功。在程序启动时分配一大块内存,然后在new_handler第一次被调用时释放它供程序使用。
(2)如果当前的new_handler不能获得更多的内存供operator new分配使用,但另一个new_handler却可以做到,则调用set_new_handler在自己的位置上安装另一个new_handler,当operator new下一次调用new_handler时,它会调用最新安装的那一个。
(3)将空指针传给set_new_handler,卸载new_handler。此时,当内存分配失败时,operator new则会抛出一个异常。
(4)抛出一个类型为bad_alloc或继承自bad_alloc的其他类型的异常。
(5)直接调用abort或exit结束应用程序。


3. set_new_handler的返回值是一个指向函数的指针,指向的是set_new_handler调用之前的异常处理函数。


4. new_handler必须有主动退出功能,否则就会导致operator new内部死循环,new_handler的一般形式:

void MemErrorHandling()
{
    if() // 如果有可能使得operator new成功
    {
        // process
        return;
    }
    // 一下任一种方式主动退出:
    // abort/exit 直接退出程序
    // 或set_new_handler(其他new_handler)
    // 或set_new_handler(NULL)
    // 或throw bad_alloc()或其派生类
}

5. 根据被分配对象的不同,采用不同的方法对内存分配失败进行处理:

// 需要为每一个class提供专属的:
// set_new_handler
// operator new
// new_handler类型的静态成员
// 将其设置为类的new-handler处理函数
class A
{
public:
    static std::new_handler set_new_handler(std::new_handler p) throw();
    static void * operator new(std::size_t size) throw(std::bad_alloc);
    static void MemoryErrorHandling();
private:
    std::new_handler m_curHandler;
};

std::new_handler A::m_curHandler = NULL;

std::new_handler A::set_new_handler(std::new_handler p) throw()
{
    std::new_handler oldHandler = m_curHandler;
    m_curHandler = p;
    return oldHandler;
}

void A::MemoryErrorHandling()
{
    // process
}

void * A::operator new(std::size_t size) throw(std::bad_alloc)
{
    set_new_handler(MemoryErrorHandling);
    return ::operator new(size);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值