共计 1380 个字符,预计需要花费 4 分钟才能阅读完成。
作者:LogM
本文原载于 https://segmentfault.com/u/logm/articles,不允许转载~
8. 定制 new 和 delete
-
8.1 条款 49:了解 new-handler 的行为
- new-handler 相当于 new 的异常处理函数。new 申请内存发生异常,调用 new-handler 处理,处理完了之后继续尝试 new,如果还是出错,继续调用 new-handler,以此反复。
-
// 标准库对于 new-handler 是这么写的://new_handler 被定义成一个函数指针 //set_new_handler 函数的参数是个指针,指向 new 无法分配足够内存时应该调用的函数;//set_new_handler 函数的返回值是个指针,指向 set_new_handler 之前设置的 new_handler 函数 namespace std {typedef void (*new_handler)(); new_handler set_new_handler(new_handler p) throw();} // 可以这样使用 set_new_handler void oufOfMem() { std::cerr << "Unalbe to new\n"; std::abort();} int main() {std::set_new_handler(outOfMem); int * pBigArray = new int[10000000000L]; }
-
一般来说,new-handler 函数会做以下事情的某几件:
- a. 让更多内存可被使用。使得再次尝试 new 能成功。
- b. 安装另一个 new-handler。使用更强力的 new-handler 处理。
- c. 卸载 new-handler。实在不行,卸载 new-handler 使 new 抛出异常。
- d. 抛出 bad_alloc 的异常。
- e. 退出程序。abort() 或 exit()。
-
8.2 条款 50:了解 new 和 delete 的合理替换时机
- 这部分讲的是:如果你觉得编译器自带的 new 和 delete 不好用,应该怎么写一个自定义的函数替换。
- 作者自己也提到了,要自定义 new 和 delete 不是简单写个函数就好了,内存的申请和释放会涉及到计算机体系架构中比较底层的东西,比如 ” 内存对齐 ”。所以重头开始写 new 和 delete 是比较复杂的,可以买现成的商业产品,或者在开源代码上修改。
-
8.3 条款 51:编写 new 和 delete 时需要固守常规
- 条款 50 已经说明了,自定义 new 和 delete 比较复杂,非必要不建议重写。
-
这部分讲了自定义 new 和 delete 时需要注意的事项:
- operator new 应该内含一个无穷循环,并在其中尝试分配内存,分配不了,调用 new-handler。
- operator new 对 0 bytes 的内存申请,也需要正常返回指针。
- operator delete 应该在收到 null 指针时不做任何事。
-
8.4 条款 52:写了 placement new 也要写 placement delete
-
Widget* pw = new Widget // 这句话中总共有 2 个函数被调用:1.operator new 分配内存;2.Widget 的构造函数 // 当调用 Widget 构造函数发生异常时,需要 delete 掉第一步 new 出来的内存 // 如果使用 C ++ 自带的 new 和 delete,这个情况不需要用户考虑;如果是自定义 new 和 delete,需要用户考虑
-
正文完