web-dev-qa-db-ja.com

新しいstd :: nothrowバージョンが広く使用されていない理由

C++リファレンス によると、次の方法でオブジェクトを新規作成できます。

_MyClass * p1 = new MyClass;
_

またはによって

_MyClass * p2 = new (std::nothrow) MyClass;
_

2つ目は、例外をスローする代わりにnullポインターを返します。

しかし、私の経験ではこのバージョンはほとんど見られません。

たとえば、Googleはコードで例外を使用することを推奨していませんが、私が見ることができるように、Chromiumでもnothrowバージョンを使用していません。

Nothrowよりもデフォルトのものを好む理由はありますか?例外を使用していないプロジェクトでも?

-編集-

フォローアップの質問:malloc()の戻り値を確認する必要がありますか?

それどころか、mallocの戻り値を確認するようにアドバイスする人が多いようです。

多くの割り当ての失敗は、メモリ不足とは何の関係もありません。十分な空きメモリがあるにもかかわらず、使用可能な連続スペースが十分にないため、断片化によって割り当てが失敗する可能性があります。

これは本当ですか?この場合、なぜmalloc()new()を異なる方法で扱うのですか?

22
Deqing

しかし、私の経験ではこのバージョンはほとんど見られません。

ローカルで障害を処理できる場合は、これを使用します(または、同等に、デフォルトバージョンからの例外をキャッチします)。おそらく、他のメモリを解放するように要求してから再試行するか、より小さなものを割り当てようとするか、追加のメモリを必要としない代替アルゴリズムを使用します。

Nothrowよりもデフォルトのものを好む理由はありますか?

例外の一般原則:ローカルで処理できない場合は、ローカルでチェックしても意味がありません。戻り値とは異なり、例外は無視できないため、nullポインターを使用して関係なく実行する可能性はありません。

例外を使用していないプロジェクトでも?

多くの場合、メモリ不足状態はまったく処理できません。その場合、プログラムを終了することがおそらく最善の対応です。これは、未処理の例外に対するデフォルトの応答です。したがって、例外を使用していない場合でも、ほとんどの状況でデフォルトのnewがおそらく最良のオプションです。

malloc()の戻り値を確認する必要がありますか?

はい:それが成功したかどうかを確認する唯一の方法です。そうしないと、nullポインターを使用して、未定義の動作を引き起こす可能性があります。多くの場合、クラッシュしますが、データの破損やその他の奇妙な動作、および(うまくいけば)何が悪かったのかを理解するための長いデバッグセッションがあります。

この場合、なぜmalloc()newを異なる方法で扱うのですか?

mallocは戻り値のチェックを強制するのに対し、newは煩わしくないエラー処理のオプションを提供するためです。

34
Mike Seymour

スローバージョンを使用する場合、すべてのnew呼び出しの結果をテストして、成功したか失敗したかを確認する必要はありません。通常、多くの/ほとんどのアプリケーションで、割り当てが失敗した場合、多くのことを実行できず、終了/中止するだけです。明示的に試行/キャッチしないと、例外が自動的に実行されます。

nothrowバージョンを使用すると、アプリケーションを介してnullポインターが伝播し、後でメモリ割り当てとはまったく関係のない時点でクラッシュ/終了する可能性があり、デバッグがはるかに困難になります。

7
Mark B