关闭

编写高质量代码:改善C++程序的150个建议(连载16)

发表于:2012-4-25 09:43

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:李健    来源:51Testing软件测试网采编

  建议31:了解new_handler的所作所为

  在使用operator new申请内存失败后,编译器并不是不做任何的努力直接抛出std::alloc异常,在这之前,它会调用一个错误处理函数(这个函数被称为new-handler),进行相应的处理。通常,一个好的new-handler函数的处理方式必须遵循以下策略之一:

  Make more memory available(使更大块内存有效)

  operator new会进行多次的内存分配尝试,这可能会使其下一次的内存分配尝试成功。其中的一个实现方法是在程序启动时分配一大块内存,然后在new-handler第一次被调用时释放它供程序使用。

  Install a different new-handler(装载另外的new-handler)

  程序中可以同时存在多个new-handler,假如当前的new-handler不能获得更多的内存供operator new分配使用,但另一个new-handler却可以做到。在这种情形下,当前的 new-handler则会通过调用set_new_handler在它自己的位置上安装另一个new-handler。当operator new 下一次调用 new-handler时,它会调用最新安装的那一个。

  Deinstall the new-handler(卸载new-handler)

  换句话说,就是将空指针传给set_new_handler,此时就没有了相应的new-handler。当内存分配失败时,operator new则会抛出一个异常。

  Throw an exception(抛出异常)

  抛出一个类型为bad_alloc或继承自bad_alloc的其他类型的异常。

  Not return(无返回)

  直接调用abort或exit结束应用程序。

  以上的这些处理方式让我们在实现new-handler functions时拥有了更多的选择与自由。这些各式各样的new-handler函数是可以通过调用标准库函数set_new_handler进行特殊定制的,你可以按照自己的方式来对编译器的这一行为进行设定。这个函数同样也声明在 <new> 中:

  1. namespace std  
  2. {  
  3.  typedef void (*new_handler)();  
  4.  new_handler set_new_handler(new_handler p) throw();  
  5. }

  通过函数声明可以看到set_new_handler的形参是一个指向函数的指针,这个函数在 operator new无法分配被请求的内存时调用。set_new_handler的返回值是一个指向函数的指针,指向的是set_new_handler调用之前的异常处理函数。所以,可以按照以下方式使用set_new_handler函数:

  1. //error-handling function  
  2. void MemErrorHandling()  
  3. {  
  4.  std::cerr << "Failed to allocate memory\n";  
  5.  std::abort();  
  6. }  
  7. //Application  
  8. const long long DATA_SIZE = 1024*1024*1024;  
  9. int main()  
  10. {  
  11.      std::set_new_handler(MemErrorHandling);  
  12.      std::cout << "Attempting to allocate 1 GB...";  
  13.      char *pDataBlock = NULL;  
  14.      try  
  15.      {  
  16.         pDataBlock = new char[DATA_SIZE];  
  17.      }  
  18.      catch(std::alloc& e)  
  19.      {  
  20.         ... //some processing codes  
  21.      }  
  22.      ... // other processing code  
  23. }

  假如operator new分配空间的请求得不到满足,MemErrorHandling函数将被调用,程序将按照函数中的设定处理方式运行。在标准C++中,标准set_new_handler为用户类统一指定了错误处理函数global new-handler。上述代码采用的就是global new-handler形式。

51/512345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号