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 何克勤 閱讀(337) 評論(0)  編輯  收藏 所屬分類: C/C++
          主站蜘蛛池模板: 崇明县| 澳门| 九江市| 福贡县| 苍山县| 彰化县| 大足县| 包头市| 岳西县| 琼海市| 会东县| 武功县| 夏河县| 于田县| 浑源县| 彭阳县| 泸水县| 望城县| 启东市| 方正县| 迭部县| 微山县| 集贤县| 德江县| 武强县| 略阳县| 汝阳县| 中卫市| 固镇县| 武鸣县| 凤山市| 五台县| 靖江市| 綦江县| 石阡县| 镇康县| 荥经县| 铜梁县| 东方市| 江达县| 奉节县|