1. 程式人生 > 程式設計 >C++ 記憶體分配處理函式set_new_handler的使用

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;
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。