ホームページ  >  記事  >  バックエンド開発  >  ベース ポインターを持つ派生オブジェクトの配列を削除することが C で未定義の動作とみなされるのはなぜですか?

ベース ポインターを持つ派生オブジェクトの配列を削除することが C で未定義の動作とみなされるのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-01 03:42:02307ブラウズ

Why is deleting an array of derived objects with a base pointer considered Undefined Behavior in C  ?

ベース ポインタを持つ派生オブジェクトの配列を 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。