条款49:了解new-handler的行为

  • 当operator new无法分配出内存会抛出异常std::bad_alloc
  • 抛出异常前会反复调用用户自定义的new-handler函数直至成功分配内存
  1. // 自定义new_handler函数
  2. void outOfMem() {
  3. cerr << "Unable to satisfy request for memory" << endl;
  4. abort();
  5. }
  6. //测试
  7. int main() {
  8. set_new_handler(outOfMem); //写入new_handler函数
  9. int* pBigDataArray = new int[100000000000000000L];
  10. return 0;
  11. } //输出 :Unable to satisfy request for memory
  12. //声明于<new>中的标准程序函数
  13. namespace std {
  14. typedef void (*new_handler) ();
  15. new_handler set_new_handler(new_handler p) throw();
  16. }
  • 为不同的class写不同的new-handler函数
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. class NewHandlerHolder {
  6. public:
  7. explicit NewHandlerHolder(new_handler nh)
  8. : handler(nh) {}
  9. ~NewHandlerHolder() {std::set_new_handler(handler);}
  10. private:
  11. new_handler handler;
  12. NewHandlerHolder(const NewHandlerHolder&) {}
  13. NewHandlerHolder& operator= (const NewHandlerHolder&) {}
  14. };
  15. template<typename T>
  16. class NewHandlerSupport {
  17. public:
  18. static new_handler set_new_handler(new_handler p) throw();
  19. static void* operator new[](size_t size) throw(bad_alloc);
  20. private:
  21. static new_handler currentHandler;
  22. };
  23. template<typename T>
  24. new_handler NewHandlerSupport<T>::currentHandler = 0;
  25. template<typename T>
  26. new_handler NewHandlerSupport<T>::set_new_handler(new_handler p) throw() {
  27. new_handler oldHandler = currentHandler;
  28. currentHandler = p;
  29. return oldHandler;
  30. }
  31. template<typename T>
  32. void* NewHandlerSupport<T>::operator new[](size_t size) throw(bad_alloc) {
  33. NewHandlerHolder h(std::set_new_handler(currentHandler));
  34. return ::operator new[](size);
  35. }
  36. class Widget : public NewHandlerSupport<Widget>{
  37. };
  38. void outOfMem() {
  39. cerr << "Unable to satisfy request for memory" << endl;
  40. abort();
  41. }
  42. int main() {
  43. Widget::set_new_handler(outOfMem);
  44. Widget* pwl = new Widget[100000000000L];
  45. return 0;
  46. }

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

  • 有许多理由需要自定new和delete,包括改善性能、对heap运用错误进行调试、手机heap使用信息

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

  • operator new 应该包含一个无穷循环,并在其中尝试分配内存,如果无法满足内存需求,就调用new-handler函数,且要有能力处理 0 bytes申请。
  • operator delete应该在收到null指针时不做任何事情 

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

  • 当写new的表达式\(Widget* pw = new Widget\)时,两个函数被调用

    • 一个是用以分配内存的 operator new
    • 另一个是Widget的default构造函数
  • 如果在调用构造函数失败,编译器会寻找一个“带相同额外参数”的operator delete,找不到调用不了,会造成资源泄漏

《Effective C++》定制new和delete:条款49-条款52的更多相关文章

  1. Effective C++ —— 定制new和delete(八)

    STL容器所使用的heap内存是由容器所拥有的分配器对象管理,不是被new和delete直接管理.本章并不讨论STL分配器. 条款49 : 了解new-handler的行为 当operator new ...

  2. 【effective c++】定制new和delete

    条款49: 了解new-handler的行为 operator new 和 operator delete只适合用来分配单一对象.array所用的内存由operator new[]分配出来,并由ope ...

  3. EC读书笔记系列之19:条款49、50、51、52

    条款49 了解new-handler的行为 记住: ★set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用 ★Nothrow new是一个颇为局限的工具,∵其只适用于内存 ...

  4. 八、定制new和delete

    条款49:了解new-handler的行为 new异常会发生什么事? 在旧式的编译器中,operator new分配内存失败的时候,会返回一个null指针.而现在则是会抛出一个异常. 而在抛出这个异常 ...

  5. STL笔记(5)条款49:学习破解有关STL的编译器诊断信息

    STL笔记(5)条款49:学习破解有关STL的编译器诊断信息 条款49:学习破解有关STL的编译器诊断信息 用一个特定的大小定义一个vector是完全合法的, vector<int> v( ...

  6. 高效C++:定制new和delete

    内存的申请和释放,C++从语言级别提供了new和delete关键字,因此需要了解和熟悉其中的过程. 了解new-handler的行为 set_new_handler可以指定一个函数,当申请内存失败时调 ...

  7. Effective C++: 08定制new和delete

    49:了解new-handler的行为 当operator new无法满足某一内存分配需求时,它会抛出异常(以前会返回一个null).在抛出异常之前,它会调用一个客户指定的错误处理函数,也就是所谓的n ...

  8. Effective C++ -----条款49:了解new-handler 的行为

    set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用. Nothorw new 是一个颇为局限的工具,因为它只适用于内存分配:后继的构造函数调用还是可能抛出异常.

  9. Effective C++:条款27——条款

    条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!

随机推荐

  1. (摘)使用 .NET Core 实现依赖关系注入

    为什么使用依赖关系注入? 使用 .NET,通过 new 运算符(即,new MyService 或任何想要实例化的对象类型)调用构造函数即可轻松实现对象实例化.遗憾的是,此类调用会强制实施客户端(或应 ...

  2. [PHP] 频率限制类

    比如要实现 单个ip限制60秒1次单个关键字,比如手机号,限制60秒1次,3600秒10次 <?php class Sina_Mail_WebAntispam { const PREFIX_WH ...

  3. 2018/12/21:Date类

    1.Date类 getDate()返回一个月的某一天 1-31 getDay()返回一周的某一天 getFullyear()返回四位数的年份 getMonth()返回月份 比实际情况小 1 0代表1月 ...

  4. 深入了解浏览器存储:对比Cookie、LocalStorage、sessionStorage与IndexedDB

    摘要: 对比Cookie.LocalStorage.sessionStorage与IndexedDB 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 随着移动网络的发展与演化,我 ...

  5. Java自学总结--简介

    学习Java一年多了,练习了很多,这条路真的很难走.还有半年多毕业的我整理整理所学习的笔记给大家分享主要也是让自己记忆加深.自学时用到的时阿发老师的教学视频,通俗易懂还有题库可以练习.最经典的就是阿发 ...

  6. iOS---------- Safe Area Layout Guide before iOS 9.0

    如果你们的项目不做iOS9以下支持就打开main.storyboard    去除Use safe Area Layout 如果不考虑iOS9以下支持就按照下面的步骤 选中控制器,右边面板的Build ...

  7. Unity Profiler的使用

    选中Development Build.Autoconnect Profiler和Script Debugging三个选项,如下图所示. 点击Build And Run按钮,将会编译项目并安装APK到 ...

  8. Andriod Studio安装教程

    最近开设安卓课程,无奈于开发团队不再更新eclipse上sdk兼容问题,在eclipse上浪费了两天时间,换了Andriod Studio, Andriod Studio下载网址:http://www ...

  9. 微信小程序(六) 文章详情静态页面detail

    文章详情静态页面detail:

  10. elasticsearch常用命令

    elasticsearch的rest访问格式: curl -X<REST Verb> <Node>:<Port>/<Index>/<Type> ...