閱讀320 返回首頁    go 阿裏雲 go 技術社區[雲棲]


C++ new_handler空間分配失敗處理

C++ new_handler空間分配失敗處理

 

動態分配空間、內存動態分配與回收對於任何一個程序員來說都尤為重要,特別是嵌入式C/C++程序員更為如此,malloc, remalloc, new等等,很有可能就申請空間失敗,對申請失敗的異常處理更是比較棘手。在C++中提倡使用new來代替malloc,因為new比malloc更加安全,更加效率。

 

很多程序員,包括我自己都喜歡性的使用這種C/C++代碼來申請空間。

 

#include <iostream> #include <windows.h> using namespace std; typedef int Type; typedef struct _Node { Type data; struct _Node *next; }Node; int main(void) { Node *pNode = (Node *)(malloc(sizeof(Node))); if (!pNode) { abort(); } return 0; }

 

C++中,這裏有問題嗎?C程序員來說一般都會寫類似的代碼。

 

C++中,很多錯誤都會以異常的方式拋出,而且對於一個稍大的項目來說異常處理通常會設計專門的異常類去處理。

在《Effective C++》中則提到了一個比較智能的使用異常的方式去處理動態分配空間失敗:

 

 

//這裏先提到,詳細的解釋和代碼在後麵 new_handler; new_handler set_new_handler(new_handler p);

 

他們被定義在

#include <new> using namespace std;

 

 

new_handler和set_new_handler的申明如下:

 

//new_handler typedef void (×new_handler)(); //set_new_handler new_handler set_new_handler(new_handler p);

 

new_handler是一個參數為空的函數指針。

set_new_handler就是設置異常處理函數的入口,有程序員自己定義然後傳入。

當空間分配失敗之後,就會調用new_handler異常處理函數,然後才會拋出異常。也就是說異常的拋出是在調用new_handler之後。

 

對於一個動態內存分配失敗的異常處理函數應該至少具有以下幾個特點:

 

1.確保內存分配成功。

所謂確保內存分配成功,也就是說當new的時候不會失敗。這是一個策略問題。我們可以在調用new之前,就申請一塊較大的空間,當new空間的時候,就是放一點

 

2.設置不同的new_handler。

對於這一點,我們可以通過改變new_handler的參數以及申請空間的數量來做到。以確保下次申請空間成功。

 

3. 解除new_handler。

即傳入NULL指針。

 

4.異常拋出。

 

那麼。實際上,以上4點,set_new_handler已經可以做到了。

 

 

#include <iostream> #include <new> //new_handler,set_new_handler #include <windows.h> using namespace std; void NoMemory() { cout << "No adequate memory left" << endl; abort(); } int main(void) { set_new_handler(NoMemory); //這裏實際很難碰到申請失敗的情況 BYTE *pData = new BYTE[0x5fffffff]; return 0; }

 

 

實際上,如果new_handler中沒有abort的話,new_handler會被循環的調用下去,直到申請空間成功為止。

 

 

最後更新:2017-04-02 06:51:38

  上一篇:go 在Ubuntu中用Android NDK編譯FFmpeg
  下一篇:go 電腦屏幕健康色