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组件实现品,以及其他许多程序库。