Effective C++ 随记 第八章(定制 new 和 delete )第九章(杂谈)

new 和 delete只适合用来分配和回收单一对象,数组需要使用 newP[] 和 delete[]。

STL容器使用的 堆内存 由容器拥有的分配器对象(allocator object)管理,不是new和delete直接管理。

 

条款49:了解 new_handler的行为

1:让更多的内存可被使用——开始执行时分配一大块内存,当new_handler被调用时将内存释还给程序使用。

2:安装另一个new_handler——当前的new_handler无法取得更大的内存,且知道哪一个有能力取得更大的内存,安装新的new_handler。

3:卸除new_handler——将null传递给set_new_handler。没有安装new_handler时,new会在内存分配失败时抛出异常。

4:抛出bad_alloc(此类)的异常——异常不会被new捕获,会传递到内存所求处。

5:不返回——调用abort或exit函数退出程序。

请记住:

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

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

 

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

替换编译器提供的operator new或operator delete的理由:
1:用来检测运用上的错误——没有适当运用delete、超额分配内存;

2:强化效能——编译器提供的版本难以长时间使用、内存分配(内存破碎问题无法适用于特殊场景-大块内存、小块内存、尺寸混合内存);

3:收集使用上的统计数据——为了确定内存的大小分布、分配/归还的顺序、分配/归还形态是否随时间变化;

4:为了增加分配和归还的速度——使用该理由前需要先确定程序的瓶颈在于内存函数中;

5:为了降低缺省内存管理器带来的空间额外开销;

6:为了弥补缺省分配器中的非最佳齐位——如X86体系结构上double 的方位最快速为 8-bits齐位数据;

7:为了将相关对象成簇集中——若知道数据结构往往被一起使用,同时希望降低“内存页错误”的可能性,为此类数据结构创建新的heap,保证其集中在较少的内存页中;

8:为了获得非传统行为——例如清除内存同时将其内容覆盖为0(保护数据)。

请记住:

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

 

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

申请0 bits内存也会返回一个合法指针——视为1 bits内存处理

动态分配 array 可能包含额外的内存存放元素个数——稍大的实际内存分配

 

删除null指针永远正确——什么都不做直接返回。

请记住:

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

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

 

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

normal new/delete

static void* operator new(std::size_t_size) throw(std::bad_alloc);

static void operator delete(void* pMemory) throw();  

placement new/delete:

static void* operator new(std::size_t_size, void* ptr) throw();

Static void operator delete(void* pMemory, void* ptr) throw();

nothrow new/delete

static void* operator new(std::size_t_size, const std::nothrow_t& nt) throw();

Static void operator delete(void* pMemory, const std::nothrow_t&) throw();

一个内含placement new/delete 的class应该包含的全部new/delete 组合。

 

placement delete 只有在placement new调用出现异常时才会使用,正常情况下释放一个指针不会调用placement delete。

请记住:

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

2):当你声明placement new和placement delete,请确定不要无意识的掩盖了它们的正常版本。

 

条款53:不要轻忽编译器的警告

请记住:

1):严肃对待编译器发出的警告信习。努力在你的编译器最高警告级别下争取无任何警告的荣誉。

2):不要过度依赖编译器的报警能力,因为不同的编译器对待事情的态度并不相同。一代移植到另一个编译器上,你所依赖的警告信息有可能消失。

 

条款54:让自己熟悉包括TR1在内的标准程序库

请记住:

1):C++标准程序库的主要机能由STL、iostream、locale组成,并包含C99标准程序库.

2):TR1添加了智能指针、一般化函数指针、hash-based的容器、正则表达式以及另外的10个组件支持。

3):自身只是一份规范。为了获得PR1的好处你需要一份实物,一个好的实物来源是boost。

条款55:让自己熟悉Boost

请记住:

1):Boost是一个社群,也是一个网站。致力于免费、源码开放、同僚复审的C++程序库开发。boost在C++标准化过程中扮演深具影响力的角色。

2):boost提供许多TR1组件实现品,以及其他许多程序库。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值