c++でのC++標準指定の動作は何newですか?
通常の概念では、newオペレーターが要求されたサイズの動的メモリーを割り当てることができない場合、 type の例外をスローする必要がありますstd::bad_alloc。ただし、例外がスロー
される前であっても、さらに何かが発生します。bad_alloc
C++03 セクション 3.7.4.1.3:言う
ストレージの割り当てに失敗した割り当て関数は、現在インストールされている new_handler(18.4.2.2) があればそれを呼び出すことができます。[注: プログラム提供の割り当て関数は、set_new_handler 関数 (18.4.2.3) を使用して、現在インストールされている new_handler のアドレスを取得できます。] 空の例外仕様 (15.4) で宣言された割り当て関数 throw() が、ストレージを割り当てると、null ポインターが返されます。ストレージの割り当てに失敗したその他の割り当て関数は、クラス std::bad_alloc (18.4.2.1) または std::bad_alloc から派生したクラスの例外をスローすることによってのみ失敗を示します。
次のコード サンプルを検討してください。
#include <iostream>
#include <cstdlib>
// function to call if operator new can't allocate enough memory or error arises
void outOfMemHandler()
{
std::cerr << "Unable to satisfy request for memory\n";
std::abort();
}
int main()
{
//set the new_handler
std::set_new_handler(outOfMemHandler);
//Request huge memory size, that will cause ::operator new to fail
int *pBigDataArray = new int[100000000L];
return 0;
}
上記の例では、operator new(ほとんどの場合) 100,000,000 個の整数にスペースを割り当てることができず、関数outOfMemHandler()が呼び出され、プログラムはエラー メッセージを発行した後に中止されます。
newここで見られるように、メモリ要求を満たすことができない場合の operator のデフォルトの動作は、new-handler十分なメモリが見つかるか、新しいハンドラがなくなるまで関数を繰り返し呼び出すことです。上記の例では、 を呼び出さない限りstd::abort()、outOfMemHandler()が繰り返し呼び出されます。したがって、ハンドラーは、次の割り当てが成功することを確認するか、別のハンドラーを登録するか、ハンドラーを登録しないか、戻らない (つまり、プログラムを終了する) 必要があります。新しいハンドラーがなく、割り当てが失敗した場合、オペレーターは例外をスローします。
new_handlerととは何set_new_handlerですか?
new_handlerは、何も受け取って何も返さない関数へのポインタの typedef であり、 を受け取って返すset_new_handler関数ですnew_handler。
何かのようなもの:
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
newset_new_handler のパラメーターは、要求されたメモリを割り当てることができない場合にオペレーターが呼び出す関数へのポインターです。その戻り値は、以前に登録されたハンドラー関数へのポインター、または以前のハンドラーがなかった場合は null です。
C++でメモリ不足の状態を処理するには?
new適切に設計されたユーザー プログラムの動作を考えるとnew_handler、次のいずれかを実行 する適切なメソッドを提供することにより、メモリ不足の状態を処理する必要があります。
より多くのメモリを利用できるようにする:これにより、演算子 new のループ内での次のメモリ割り当ての試行が成功する可能性があります。これを実装する 1 つの方法は、プログラムの起動時に大きなメモリ ブロックを割り当て、new-handler が最初に呼び出されたときにプログラムで使用するために解放することです。
別の new-handler をインストールする:現在の new-handler がこれ以上メモリを使用可能にできず、別の new-handler が使用できる場合、現在の new-handler はその場所に他の new-handler をインストールできます (を呼び出すことによってset_new_handler)。次に new 演算子が new-handler 関数を呼び出すと、最後にインストールされたものが取得されます。
(このテーマのバリエーションは、new-handler が独自の動作を変更するためのものです。そのため、次に呼び出されたときに別のことを行います。これを実現する 1 つの方法は、new-handler に静的、名前空間固有、またはnew-handler の動作に影響するグローバル データ)。
new-handler をアンインストールします。 これは、null ポインターを に渡すことによって行われますset_new_handler。new-handler がインストールされていない場合、メモリの割り当てに失敗operator newすると、例外 ((convertible to) ) がスローされます。std::bad_alloc
に変換可能な例外をスローしますstd::bad_alloc。このような例外は によってキャッチされませんがoperator new、メモリの要求を発信したサイトに伝搬されます。
返さない:abortまたはを呼び出すことによってexit。