posts - 134,comments - 22,trackbacks - 0

1,当operator new无法满足内存需求时,抛出std::bad_alloc.
下面是一个验证的代码:

Cpp代码 复制代码
  1. #include <iostream>   
  2. #include <stdexcept>   
  3. using namespace std ;   
  4.   
  5. int main ()   
  6. {   
  7.     try  
  8.     {   
  9.         int* p=NULL;   
  10.         while(1)   
  11.             p=new int[10000];   
  12.     }catch(std::bad_alloc&)   
  13.     {   
  14.         cout<<"no enough mem."<<endl;   
  15.     }   
  16.     return 0 ;   
  17. }  



2,C++的一个公约:
当operator new无法满足需求时,它会在抛出exception前先调用一个专属的错误处理函数.
我们称之为:new-handler.

3,当operator无法满足内存需求时,它会不只一次的调用new-handler函数;
它会不断的重复调用,直到找到足够的内存.
一个设计良好的new-handler函数必须完成下面几件事:
(1)让更多内存可用.
例如:事先在程序起始处配置一大块内存,然后在new-handler第一次被调用时释放之.
(2)配置另外一个new-handler,其手上握有比较多的资源.
(3)卸除new-handler,set_new_handler(NULL)
将不再调用专属函数,而直接抛出exception.
(4)抛出exception.
(5)不回返,直接调用abort()或exit.

Cpp代码 复制代码
  1. #include <iostream>   
  2. #include <stdexcept>   
  3. using namespace std ;   
  4.   
  5. void noMoreMemory()   
  6. {   
  7.     cout<<"Unable to satify request for memory."<<endl;   
  8.     //原则(5):不回返   
  9.     abort();//不加,将会是一个死循环.   
  10.     //原则(4):也可以通过抛出一个异常   
  11.     //throw std::bad_alloc();   
  12. }   
  13.   
  14. int main ()   
  15. {   
  16.     //typedef void (*new_handler)();  头文件中已经给出   
  17.     //设定自己的专属错误处理函数.   
  18.     //返回之前的new_handler   
  19.     new_handler old_new_handler=set_new_handler(noMoreMemory);   
  20.     //set_new_handler(NULL); //卸除new-handler,抛出异常.   
  21.     try  
  22.     {   
  23.         int* p=NULL;   
  24.         while(1)   
  25.             p=new int[10000];   
  26.     }catch(std::bad_alloc&)   
  27.     {   
  28.         cout<<"no more memory."<<endl;   
  29.         set_new_handler(old_new_handler);   
  30.     }   
  31.     set_new_handler(old_new_handler);   
  32.     return 0 ;   
  33. }  


4,设定类class专属的new-handler.
一个强大的类模板.

Cpp代码 复制代码
  1. #include <iostream>   
  2. #include <stdexcept>   
  3. using namespace std ;   
  4.   
  5. template<class T>   
  6. class NewHandlerSupport   
  7. {   
  8. public:   
  9.     static new_handler set_new_handler(new_handler p);   
  10.     static void* operator new(size_t size);   
  11.     static void* operator new[](size_t size);   
  12. private:   
  13.     static new_handler currentHandler;   
  14. };   
  15.   
  16. template<class T>   
  17. new_handler NewHandlerSupport<T>::set_new_handler(new_handler p)   
  18. {   
  19.     new_handler oldHandler=currentHandler;   
  20.     currentHandler=p;   
  21.     return oldHandler; //返回之前的专属函数   
  22. }   
  23.   
  24. template<class T>   
  25. void* NewHandlerSupport<T>::operator new(size_t size)   
  26. {   
  27.     //下面调用标准的set_new_handler   
  28.     new_handler globalHandler=std::set_new_handler(currentHandler);   
  29.   
  30.     void* memory;   
  31.     try  
  32.     {   
  33.         //使用标准的new.   
  34.         memory=::operator new(size);   
  35.     }catch(std::bad_alloc)   
  36.     {   
  37.         std::set_new_handler(globalHandler);   
  38.         throw//继续抛出异常   
  39.     }   
  40.   
  41.   
  42.     std::set_new_handler(globalHandler); //返回原来的设置   
  43.     return memory; //返回之前的专属函数   
  44. }   
  45.   
  46. template<class T>   
  47. static void* NewHandlerSupport<T>::operator new[](size_t size)   
  48. {   
  49.     return operator new(size);   
  50. }   
  51.   
  52. template<class T>   
  53. new_handler NewHandlerSupport<T>::currentHandler; //设置为0   
  54.   
  55. void noMoreMemory()   
  56. {   
  57.     cout<<"Unable to satify request for memory."<<endl;   
  58.     //abort();   
  59.     throw std::bad_alloc();   
  60. }   
  61.   
  62. class X : public NewHandlerSupport<X>   
  63. {   
  64. };   
  65.   
  66. int main ()   
  67. {   
  68.     X::set_new_handler(noMoreMemory);   
  69.     try  
  70.     {   
  71.         X* p=NULL;   
  72.         //先调用专属函数,然后有专属函数抛出异常.   
  73.         while(1)   
  74.             p=new X[100000];   
  75.     }catch(std::bad_alloc&)   
  76.     {   
  77.         cout<<"no more memory."<<endl;   
  78.     }   
  79.   
  80.     X::set_new_handler(0);   
  81.     try  
  82.     {   
  83.         X* p=NULL;   
  84.         //不再调用专属函数,直接捕获异常.   
  85.         while(1)   
  86.             p=new X[100000];   
  87.     }catch(std::bad_alloc&)   
  88.     {   
  89.         cout<<"no more memory."<<endl;   
  90.     }   
  91.     return 0 ;   
  92. }  


5,旧的编译器:
如果内存配置失败不会抛出异常,只是返回0.
测试实例:
int* p=new (nothrow)int;
if(p==0)
cout<<"memory error;"<<endl;

posted on 2010-05-13 14:37 何克勤 阅读(327) 评论(0)  编辑  收藏 所属分类: C/C++

只有注册用户登录后才能发表评论。


网站导航: