Effective C++ 条款49:了解 new-handler 的行为

条款49:了解 new-handler 的行为

STL 容器使用的堆内存由容器的分配器对象管理,而不是直接通过 newdelete 管理。new-handler 是一个在内存分配失败时被调用的函数,可以帮助处理内存不足的情况。


使用场景

  1. 内存分配失败的处理
    new 无法成功分配内存时,new-handler 被调用。可以使用 set_new_handler 安装一个新的 new-handler,以便在内存分配失败时采取特定的处理措施。

  2. 避免直接抛出异常
    在内存分配失败的情况下,new-handler 可以选择让更多内存可用、安装新的 new-handler、卸载当前的 new-handler,或者抛出 bad_alloc 异常。

  3. Nothrow new
    nothrow 版本的 new 运算符可以避免抛出异常,但它依然可能由于后续的构造函数调用而抛出异常,因此它的应用相对局限。


示例:设置 custom new-handler

#include <iostream>
#include <new>  // for std::set_new_handler

void custom_new_handler() {
    std::cerr << "Memory allocation failed. Custom handler activated.\n";
    std::terminate();  // Can choose to terminate or handle accordingly
}

int main() {
    std::set_new_handler(custom_new_handler);

    try {
        int* p = new int[10000000000];  // Likely to fail
    } catch (const std::bad_alloc& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

在这个示例中,set_new_handler 安装了一个自定义的内存分配失败处理函数 custom_new_handler,当内存分配失败时,它会输出错误信息并终止程序。


注意事项

  1. 设计良好的 new-handler 函数
    设计一个好的 new-handler 函数时,它必须处理内存释放、安装新的 new-handler 或卸载当前的 new-handler,并抛出 bad_alloc 异常来通知内存分配失败。

  2. Nothrow new 的局限性
    尽管 nothrow 版本的 new 不会抛出异常,但它并不是万无一失的,因为后继的构造函数调用仍然可能抛出异常,因此使用时要小心。

  3. 异常处理
    内存分配失败时,new-handler 可以选择抛出异常,或者直接终止程序。具体选择取决于应用程序的需求和设计。


总结

new-handler 提供了一种灵活的方式来处理内存分配失败的情况。通过设置合适的 new-handler 函数,程序可以在内存不足时采取不同的措施,如释放更多内存、安装新的处理程序,或终止程序。对于现代 C++ 开发者,理解 new-handler 的使用和局限性至关重要,以便设计高效且稳定的内存管理机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值