多线程环境下的内存管理,遭受单线程系统不曾有过的挑战。由于heap是一个可被改动的全局性次源,因此多线程系统充斥着发狂访问这一类资源的race conditions(竞速状态)出现机会。
四十九、条款49-了解new-handler的行为
1.当operator new抛出异常以反映一个未获满足的内存需求之前,它会先调用一个客户指定的错误处理函数,一个所谓的new-handler。为了指定这个“用以处理内存不足”的函数,客户必须调用set_new_handler,那是声明于<new>的一个标准程序库函数:
namespace std
{
typedef void (*new_handler)();
new_handler set_new_handler ( new_handler p ) throw();
}
2.设计良好的new-handler函数必须做以下事情:
[1]让更多内存可被使用
[2]安装另一个new-handler
[3]卸除new-handler
[4]抛出bad_alloc(或派生自bad_alloc)的异常
[5]不返回
3.Nothrow new是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是可能抛出异常
五十、条款50-了解new和delete的合理替换时机
1.有许多理由需要写个自定的new和delete,包括改善效能、对heap运用错误进行调试、收集heap使用信息。
[1]为了检测运用错误
[2]为了收集动态分配内存之使用统计信息
[3]为了增加分配和归还的速度
[4]为了降低缺省内存管理器带来的空间额外开销
[5]为了弥补缺省分配器中的非最佳齐位(suboptimal alignment)
[6]为了将相关对象成簇集中
[7]为了获得非传统行为
五十一、条款51-编写new和delete时需固守常规
1.operator new应该内含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存要求,就该调用new-handler。它也应该有能力处理0 bytes申请。Class专属版本则还应该处理“比正确大小更大的(错误)申请”
2.operator delete应该在收到null指针时不做使用事。Class专属版本则还应该处理“比正确大小更大的(错误)申请”
五十二、条款52-写了placement new也要写placement delete
1.当你写了一个placement operator new,请确定也写出了对应的placement operator delete。如果没这么做,你的程序可能会发生隐微而时续时断的内存泄漏
2.当你声明placement new和placement delete,请确定不要无意识(非故意)地遮掩了它们的正常版本