29

deletenull ポインターを ing することは何もしないことを知っています。

いずれの場合も、delete のオペランドの値がヌル ポインターの場合、操作は無効になります。
(C++ 標準5.3.5 [expr.delete] p2)

またvoid*、 type のオブジェクトがないため、デストラクタを呼び出すことができないため、ポインタの削除は未定義の動作ですvoid

最初の選択肢 ( delete object) では、delete のオペランドの値は、非配列オブジェクトへのポインター、またはそのようなオブジェクトの基本クラスを表すサブオブジェクトへのポインターでなければなりません。そうでない場合、動作は未定義です。
(C++ 標準5.3.5 [expr.delete] p2)

さて、通常は最初にリストされたものは後でリストされたものよりも優先されると思いますvoid*が、次のようなヌルポインターはどうですか?

void* p = 0;
delete p; // UB or well-defined?
4

3 に答える 3

13

ポインターが null の場合にのみポインターを削除する状況にどのように到達できるのだろうか。しかし、言語弁護士モードにとどまります...

C++ 03 で

5.3.5/1

delete のオペランドは、ポインター型またはポインター型への単一の変換を持つクラス型を持つ必要があります。

void* はポインター型であるため、null void ポインターは静的要件を満たします。

5.3.5/2

delete[と] のどちらの選択肢delete[]でも、delete のオペランドの値が null ポインターの場合、操作は無効です。

これにより、必要な動作が得られます。

5.3.5/3

最初の選択肢 (オブジェクトの削除) では、オペランドの静的型がその動的型と異なる場合、静的型はオペランドの動的型の基本クラスであり、静的型は仮想デストラクタを持つか、動作が未定義です。 .

これは関係ありません。null ポインターは、追加の制約をチェックするオブジェクトを参照しません。

C++ 0X では

5.3.5/1

オペランドには、オブジェクト型へのポインター、またはオブジェクト型へのポインターへの単一の非明示的な変換関数 (12.3.2) を持つクラス型が必要です。

void* はオブジェクト型へのポインターではないため、拒否する必要があります。

于 2011-05-30T14:08:00.533 に答える
8

§5.3.5/3 によると、

最初の選択肢 (オブジェクトの削除) では、オペランドの静的型がその動的型と異なる場合、静的型はオペランドの動的型の基本クラスであり、静的型は仮想デストラクタを持つか、動作が未定義です。 . 2 番目の選択肢 (配列の削除) では、削除するオブジェクトの動的な型がその静的な型と異なる場合、動作は未定義です73

脚注には、次のように書かれています。

73 -これは、タイプ void のオブジェクトがないため、タイプ void* のポインターを使用してオブジェクトを削除できないことを意味します。

そうそう、そのUBです。

未定義の動作の都市に入ると、その動作が未定義の動作の都市にすでに居住しているという理由で、その動作を正確に定義したままにすることはできないため、その動作が無効かどうかは問題ではありません。


編集:

同じことを引用し、そのUBを言う別のトピックを取得しました:

void ポインターを削除しても安全ですか?

于 2011-05-30T04:33:29.007 に答える
2

私はその未定義の動作を信じています。new voidは許可されていません ( type のオブジェクトを作成することは許可されていません) ため、 aをvoid呼び出しても意味がありません。を指しているかどうかは関係ありません。コードのどこにもそのようなものを使用することはありません。deletevoid*NULL

于 2011-05-30T04:32:04.360 に答える