读书笔记Effective-C08定制new和delete

19次阅读

共计 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,需要用户考虑 

正文完
 0