[迷信] new に失敗すると NULL が返る。

new 式はいくつかの場合に失敗します。ひとつはメモリの割り付けに失敗した場合、もうひとつはコンストラクタによる初期化に失敗した場合です。昔の、例外処理がなかったころの C++ 処理系が、new によるメモリ割り付けに失敗した場合に空ポインタ(NULL)を返していたという歴史的経緯から、現在でもなお、new 式に失敗した場合には空ポインタが返ってくると信じているプログラマが少なくありません。

しかし実際には、new 式が空ポインタを返す状況というのはかなり限定されます。具体的には、割り付け関数 operator new が空の例外指定(throw())を持ち、かつ割り付けに失敗した場合だけです。その場合、operator new が空ポインタを返したときには、生成しようとしたクラスのコンストラクタが呼び出されることなく、new は空ポインタに評価されます。

それ以外の場合、operator new がメモリ割り付けに失敗すると std::bad_alloc が送出されることを前提とした扱いを受けることになります。ユーザー定義のクラスで operator new を多重定義する場合、throw() を付けることなく、失敗時に空ポインタを返すような実装をすることはできません。

また、std::nothrow を受け取る形式の new など、例外指定 throw() を持つ割り付け関数を使用する場合であっても、メモリ割り付けに成功し、コンストラクタで失敗した場合には、空ポインタが返るのではなく、コンストラクタから例外が送出されることで new 式が中断されることになります。したがって、たとえ std::nothrow を受け取る形式の new であっても、new 式の結果が空ポインタかどうかを判定するだけでは不十分です。それと同時に、コンストラクタから送出される例外に備える必要があるのです。

このエントリーを含むはてなブックマーク