Heim >Backend-Entwicklung >C++ >Warum ist das Löschen eines abgeleiteten Arrays über einen Basiszeiger ein undefiniertes Verhalten in C?

Warum ist das Löschen eines abgeleiteten Arrays über einen Basiszeiger ein undefiniertes Verhalten in C?

Barbara Streisand
Barbara StreisandOriginal
2024-10-31 16:54:02551Durchsuche

Why is Deleting a Derived Array via a Base Pointer Undefined Behavior in C  ?

Warum undefiniertes Verhalten: Abgeleitetes Array über Basiszeiger löschen

Der C 03-Standard spezifiziert das Löschen eines Arrays abgeleiteter Objekte über einen Basiszeiger ist undefiniertes Verhalten. Dies ist auf den Unterschied zwischen dem statischen und dem dynamischen Typ des zu löschenden Objekts zurückzuführen.

Statischer vs. dynamischer Typ

Der statische Typ eines Zeigers ist der Typ im Code deklariert, während der dynamische Typ der tatsächliche Typ des Objekts ist, auf das gezeigt wird. Im Beispielcode:

<code class="cpp">struct B { virtual ~B() {} };
struct D : B {};

B* p = new D[20];</code>

Der statische Typ von p ist B*, während der dynamische Typ von *p D ist.

Undefiniertes Verhalten

Der Standard besagt, dass bei der zweiten Alternative (Array löschen) das Verhalten undefiniert ist, wenn sich der dynamische Typ vom statischen Typ unterscheidet. Dies liegt daran, dass p nicht auf den Anfang des Arrays von D-Elementen zeigt. Es zeigt auf das B-Unterobjekt des ersten Elements. Löschen Sie es daher mit delete [] p; ist ungültig.

Überlegungen zur Implementierung

Um diese Regel in einer Implementierung durchzusetzen, müsste der Compiler den dynamischen Typ des Arrays bestimmen und p dann dynamisch in diesen Typ umwandeln vor dem Löschen. Dies würde jedoch in Fällen, in denen kein Polymorphismus verwendet wird, zu unnötigem Mehraufwand führen.

Polymorphe Arrays

Wenn Sie ein Array mit polymorphem Verhalten benötigen, können Sie ein eigenes erstellen Eigene Implementierung unter Nutzung der vorhandenen Möglichkeiten von C . Sie könnten beispielsweise eine Klassenvorlage erstellen, die ein Array von Zeigern auf abgeleitete Objekte umschließt:

<code class="cpp">template <typename T>
class PolymorphicArray {
public:
    PolymorphicArray(size_t size) : _size(size), _data(new T*[_size]) {}
    ~PolymorphicArray() { delete[] _data; }
    T*& operator[](size_t index) { return _data[index]; }

private:
    size_t _size;
    T** _data;
};</code>

Diese Klasse ermöglicht Ihnen die Verwendung von polymorphem Verhalten für ein Array abgeleiteter Objekte, ohne den Standard zu verletzen.

Das obige ist der detaillierte Inhalt vonWarum ist das Löschen eines abgeleiteten Arrays über einen Basiszeiger ein undefiniertes Verhalten in C?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn