C++ 記憶體分配處理函式set_new_handler的使用
一、函式的定義
函式在namespace std中有如下定義(C++98與C++11版本不一致):
Typedef void (*new_handler)(); new_handler set_new_handler(new_handler new_p) throw(); //C++98 new_handler set_new_handler (new_handler new_p) noexcept; //C++11
二、函式介紹
該函式的作用是:當new操作或new[]操作失敗時呼叫引數所指的new_p函式
異常安全:
- C++98、C++11分別在函式後面使用了throw()、noexcept宣告,所以該函式(set_new_handler)不會丟擲異常
- 注意:如果new_p是沒有實現適當功能的函式指標(見下面的引數說明),或者如果new_p是無效的指標,它會導致未定義的行為
資料爭用:
- 呼叫此函式不會引入資料競爭,任何這樣的呼叫將會和隨後set_new_handler和set_new_handler的呼叫同步
- 注意,此要求僅適用於set_new_handler函式,但對於作為引數(new_p)傳遞的新處理函式卻非必須
函式說明
1. set_new_handler函式的作用是設定new_p指向的函式為new操作或new[]操作失敗時呼叫的處理函式。
2. 設定的處理函式可以嘗試使更多空間變為可分配狀態,這樣新一次的new操作就可能成功。當且僅當該函式成功獲得更多可用空間它才會返回;否則它將丟擲bad_alloc異常(或者繼承該異常的子類)或者終止程式(例如呼叫abort或exit)。
3. 如果設定的處理函式返回了(例如,該函式成功獲得了更多的可用空間),它可能將被反覆呼叫,直到記憶體分配成功,或者它不再返回,或者被其它函式所替代。
4. 在尚未用set_new_handler設定處理函式,或者設定的處理函式為空時,將呼叫預設的處理函式,該函式在記憶體分配失敗時丟擲bad_alloc異常。
三、函式的引數
new_p:
- 當new操作或new[]操作失敗時呼叫的函式
- 該函式引數列表為空,且返回值型別為void
- 該函式可以嘗試獲得更多的可用空間,或者丟擲異常,或者終止程式
- 如果是一個空指標或0,處理函式將被重置為預設值(將會執行丟擲bad_alloc異常)
設定的處理函式可以嘗試使更多空間變為可分配狀態,這樣新一次的new操作就可能成功。當且僅當該函式成功獲得更多可用空間它才會返回;否則它將丟擲bad_alloc異常(或者繼承該異常的子類)或者終止程式(例如呼叫abort或exit)
如果設定的處理函式返回了(例如,該函式成功獲得了更多的可用空間),它可能將被反覆呼叫,直到記憶體分配成功,或者它不再返回,或者被其它函式所替代
如果未設定處理函式,或者設定的處理函式為空時,將呼叫預設的處理函式,該函式在記憶體分配失敗時丟擲bad_alloc異常
四、函式的返回值
- 返回先前被設定的處理函式指標
- 如果set_new_handler引數為空或者已被重置,將返回空指標
- 返回的函式指標是無引數的且返回值為void型別的
五、演示案例
下面程式中new操作分配記憶體失敗時將呼叫no_memory函式
// new_handler example #include <iostream> // std::cout #include <cstdlib> // std::exit #include <new> // std::set_new_handler void no_memory () { std::cout << "Failed to allocate memory!\n"; std::exit (1); } int main () { //繫結no_memory處理函式 std::set_new_handler(no_memory); std::cout << "Attempting to allocate 1 GiB..."; char* p = new char [1024*1024*1024]; std::cout << "Ok\n"; delete[] p; return 0; }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。