ベース ポインタを持つ派生オブジェクトの配列を Delete[] するのはなぜ未定義の動作ですか?
C 標準の 5.3.5 [ expr.delete] には、「配列の削除」の場合、削除するオブジェクトの動的型が静的型と異なる場合に未定義の動作が発生することが記載されています。これは、次のコード スニペットが未定義の動作を呼び出すことを意味します:
<code class="cpp">struct B { virtual ~B() {} }; struct D : B {}; B* p = new D[20]; delete [] p; // undefined behavior</code>
未定義の動作の根拠
「delete []」操作には最初の要素へのポインタが必要です配列の。ただし、派生オブジェクトの配列へのベース ポインターを使用する場合、ポインターは実際には最初の要素のベース サブオブジェクトを参照します。したがって、「delete []」操作は、配列の最初の要素ではなく、基本サブオブジェクトを削除しようとすることになりますが、これは正しくありません。
この場合に正しい動作を強制するには、要素の型を取得する必要があります。配列を作成し、その型に対してdynamic_castを実行します。ただし、これにより、多態性が使用されていない場合でも、すべての多態性配列に不必要なオーバーヘッドが発生します。
さらに、ポインタ "p" 自体は基本サブオブジェクトのみを指すため、用途が限られています。 "p[i]" (for i > 0) などの一般的な配列操作は不可能です。
結論
「delete []」の未定義の動作" 派生オブジェクトの配列へのベース ポインターを使用することは、次のような意識的な設計上の決定です:
以上がベース ポインターを持つ派生オブジェクトの配列を削除することが C で未定義の動作とみなされるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。