C ++ Erklärung für dieses Löschen [] Error?

8

Nachdem ich viele Änderungen an einem Projekt vorgenommen habe, habe ich einen Fehler erstellt, der mich einige Zeit in Anspruch genommen hat.

Ich habe eine Klasse, die ein dynamisch zugeordnetes Array enthält. Ich erstelle dann ein dynamisches Array dieser Klasse. Ich kann dann [] dieses Array löschen. Aber wenn ich ein Element im Array vor dem Löschen ersetze, verursacht es einen Fehler. Im Debug-Modus gibt es eine Assertion-Nachricht von dbgdel.cpp "Ausdruck: _BLOCK_TYPE_IS_VALID (pHead- & gt; nBlockUse)". Hier ist ein kleines Programm zu demonstrieren.

%Vor%

Ich bin neugierig, warum passiert das? Wenn das Element im Array ersetzt wird, wird sein Destruktor aufgerufen. Dann ordnet das neue Element seine Daten an einem vom Array getrennten Ort zu. Dann löscht [] die Destruktoren aller Objekte im Array. Wenn die Destruktoren aufgerufen werden, sollten sie das Datenarray des Elements löschen. Ich kann mir nicht vorstellen, was das Problem ist, aber ich möchte, wenn jemand es erklären könnte.

    
Janz Dott 26.02.2014, 09:11
quelle

2 Antworten

9

Ihre Klasse ist kaputt: Sie hat einen nicht-trivialen Destruktor, aber Sie definieren keine Kopierkonstruktoren und kopieren keine Zuweisungsoperatoren. Das bedeutet, dass die Klasse nicht korrekt kopiert oder zugewiesen werden kann (da der zerstörbare Zustand nicht kopiert oder zugewiesen wurde), wie Sie in Ihrem Beispielcode feststellen.

Sie können entweder Ihre Klasse unkopierbar machen (in diesem Fall wird Ihr Code nicht mehr kompilieren), oder Nur verschieben , in diesem Fall müssen Sie definieren Konstruktion und Move-Zuweisung verschieben oder durch Implementierung einer tiefen Kopie der Daten richtig kopieren.

Fügen Sie folgende Definitionen hinzu:

Nicht kopierbar:

%Vor%

Nur bewegbar:

%Vor%

Kopierbar:

%Vor%

Das Ergebnis ist, dass die Natur des Destruktors die Invarianten der Klasse bestimmt, weil jedes Objekt konsistent zerstörbar sein muss. Daraus können Sie die erforderliche Semantik der Kopier- und Verschiebeoperationen ableiten. (Dies wird oft die Regel der Drei oder die Regel der Fünf genannt.)

    
Kerrek SB 26.02.2014, 09:13
quelle
5

Die Antwort von Kerrek SB ist großartig. Ich möchte nur klarstellen, dass in Ihrem Code Speicher zweimal freigegeben wird.

Dieser Code

%Vor%

ist das gleiche wie dieses

%Vor%

Dann ~ SomeClass () wird für temp aufgerufen und data wird zum ersten Mal freigegeben.

Hier

%Vor%

~ SomeClass () wird für someArray [0] aufgerufen und data wird zum zweiten Mal freigegeben.

    
Avt 26.02.2014 09:30
quelle