Effective C++:8、定制 new 和 delete

简介:

当计算环境(例如 Java 和 .NET)夸耀自己内置 “垃圾回收能力” 的当今,C++对内存管理的纯手工法也许看起来有点老气。但是许多苛刻的系统程序开发人员之所以选择 C++,就是因为它允许他们手工管理内存。这样的开发人员研究并学习他们的软件使用内存的行为特征,然后修改分配和归还工作,以求获得其所建置的系统的最佳效率(包括时间和空间)。


这样做的前提是,了解 C++ 内存管理例程的行为。这正是本章焦点。这场游戏的两个主角是分配例程和归还例程(allocation and deallocation routines,也就是 operrator new 和 operator delete),配角是 new-handler,这是当 operator new 无法满足客户的内存需要时所调用的函数。


多线程环境下的内存管理,遭受单线程系统不曾有过的挑战。由于 heap 是一个可被改动的全局性资源,因此多线程系统充斥着发狂访问这一类资源的 race conditions(竞速状态)出现机会。本章多个条款提及使用可改动之 static 数据,这总是会令线程感知(thresd-aware)程序员高度警戒如坐针毡。如果没有适当的同步控制(synchronization),一旦使用无锁(lock-free)算法或精心防止并发访问(concurrent access)时,调用内存例程可能很容易导致管理 heap 的数据结构内容败坏。我不想一再提醒你这些危险,我只打算在这里提一下,然后假设你会牢记在心。


另外要记住的是,operator new 和 operator delete 只适合用来分配单一对象。Arrays 所用的内存由 operator new [] 分配出来,并由 operator delete [] 归还(注意两个函数名称中的 [])。除非特别表示,我所写的每一件关于 operator new 和 operator delete 的事也都适合 operator new [] 和 operator delete [] 。


最后请注意,STL 容器所使用的 heap 内存是由容器所拥有的分配器对象(allocator objects)管理,不是被 new 和 delete 直接管理。本章并不讨论 STL 分配器。



条款49:了解 new-handler 行为

set_new_handler 允许客户指定一个函数,在内存分配无法获得满足时被调用。

Nothrow new 是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是可能抛出异常。



条款50:了解 new 和 delete 的合理替换时机

有许多理由需要写个自定的 new 和 delete,包括改善效能,对 heap 运用错误进行调试、收集 heap 使用信息。



条款51:编写 new 和 delete 时需固守常规

operator new 应该内含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存需求,就该调用 new-handler。它也应该有能力处理 0 bytes 申请。Class 专属版本则还应该处理 “比正确大小更大的(错误)申请” 。

operator delete 应该在收到 null 指针时不做任何事。Class 专属版本则还应该处理 “比正确大小更大的(错误)申请” 。



条款52:写了 placement new 也要写 placement delete

当你写一个 placement operator new,请确定也写出了对应的 placement operator delete。如果没有这样做,你的程序可能会发生隐微而时断时续的内存泄漏。

当你声明 placement new 和 placedelete,请确定不要无意识(非故意)地遮掩了它们的正常版本。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值