- new[meta header]
- std[meta namespace]
- type-alias[meta id-type]
namespace std {
typedef void (*new_handler)(); // C++98
using new_handler = void (*)(); // C++20
}new失敗時に呼ばれる関数の型。set_new_handler()、get_new_handler()で使用する。
new演算子は本来であれば失敗時にbad_alloc例外を送出するが、これらを使用することで、new失敗時の動作を任意の関数で置き換えられる。
ハンドラの内部では、以下のいずれかを行う必要がある:
- 確保のために利用できる領域を増やして
returnする bad_allocまたはその派生の例外を送出する- プログラムの実行を終了させる
- C++98 :
abort()もしくはexit()を呼び出す - C++11 : 呼び出し元へ戻ることなく、プログラムの実行を終了させる。
abort()やexit()のほか、quick_exit()なども使用できる
- C++98 :
#include <iostream>
#include <new>
#include <limits>
#include <cstdlib>
void on_new_failed()
{
// エラー理由を出力し、プログラムを異常終了させる
std::cout << "メモリ確保に失敗した" << std::endl;
std::abort();
}
int main()
{
// new失敗時の動作をカスタマイズ
std::new_handler handler = on_new_failed;
std::set_new_handler(handler);
auto n = std::numeric_limits<std::size_t>::max();
int* p = new int[n];
delete[] p;
}- std::new_handler[color ff0000]
- std::set_new_handler[link set_new_handler.md]
- max()[link /reference/limits/numeric_limits/max.md]
- std::abort()[link /reference/cstdlib/abort.md]
メモリ確保に失敗した
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
- C++98
- LWG Issue 994.
quick_exitshould terminate well-defined- C++11で、
new_handlerに要求される動作が「abort()もしくはexit()を呼び出す」から「呼び出し元へ戻らずにプログラムの実行を終了する」へ改められた。quick_exit()など他の終了手段も許容するため
- C++11で、