Vector zerstören
-
Wie zerstöre ich ordnungsgemäß einen Vector? Ich sehe da was von ~vector(), also
myVector.~vector()
Sieht etwas komisch aus, er meckert aber nicht rum. Ist das der rictige Weg?
-
Nein. Wenn der vector auf dem Stack allokiert wurde (wohl der Normalfall) wird er im Allgemeinen automatisch zerstört, wenn der Scope verlassen wird (also bei der schließenden Klammer }). Wenn du den Vektor dynamisch mit new allokiert hast, dann musst du ihn auch manuell mit delete löschen. In beiden Fällen wird der Destruktor automatisch aufgerufen.
-
Destructoren dürfen nicht explizit aufgerufen werden.
Mach es besser über delete myVector, wenn Du ihn dynamisch angelegt hast.
-
Hallo
1310-Logik schrieb:
Destructoren dürfen nicht explizit aufgerufen werden.
Mach es besser über delete myVector, wenn Du ihn dynamisch angelegt hast.Man darf sie wirklich nicht aufrufen? Ich dachte, dass das nur unüblich sei.
chrische
-
Ich habe ihn am Anfang einer Funktion deklariert:
vector<double> myVector;Also brauche ich am Ende nichts machen?
-
Ich auch. Ich denke man darf sie schon aufrufen (es sind schließlich "nur" Methoden), nur das Objekt danach nicht mehr benutzen.
-
Hallo
JPSelter schrieb:
Ich habe ihn am Anfang einer Funktion deklariert:
vector<double> myVector;Also brauche ich am Ende nichts machen?
Nein du musst nichts machen. Der D'tor wird wie bei jeder anderen Klasse aufgerfuen, wenn der scope verlassen wird.
.filmor schrieb:
Ich auch. Ich denke man darf sie schon aufrufen (es sind schließlich "nur" Methoden), nur das Objekt danach nicht mehr benutzen.
So dachte ich mir das auch.
chrische
-
chrische5 schrieb:
Hallo
1310-Logik schrieb:
Destructoren dürfen nicht explizit aufgerufen werden.
Mach es besser über delete myVector, wenn Du ihn dynamisch angelegt hast.Man darf sie wirklich nicht aufrufen? Ich dachte, dass das nur unüblich sei.
chrische
Naja was heisst dürfen?
Man darf auch Memoryleaks machen...
-
Hallo
1310-Logik schrieb:
chrische5 schrieb:
Hallo
1310-Logik schrieb:
Destructoren dürfen nicht explizit aufgerufen werden.
Mach es besser über delete myVector, wenn Du ihn dynamisch angelegt hast.Man darf sie wirklich nicht aufrufen? Ich dachte, dass das nur unüblich sei.
chrische
Naja was heisst dürfen?
Man darf auch Memoryleaks machen...Für mich "nicht dürfen", dass es entweder gar nicht geht, oder zu undefinierten Verhalten führt und das ist doch nicht zwangsläufig so, wenn man den D'tor aufrufst oder täusche ich mich da.
chrische
-
Das ist was anderes. Memoryleaks sind ein Fehler des Programmierers, der nicht vom Compiler geahndet wird, weil trotzdem alles legales C++ sein sollte. Ein expliziter Destruktoraufruf dagegen wäre, wenn es illegal wäre, undefiniertes Verhalten.
Aber ich denke schon, dass es geht, schließlich kann man ja auch iirc einen Konstruktor explizit auf Speicherbereiche aufrufen.
-
Einfach nur meine Frage beantworten bitte

EDIT: Oh, war beantwortet. Seid ja alle fleissig am schreiben

-
Es sind wirklich sehr spezielle Fälle, in denen der Destruktor explizit aufgerufen wird. Die STL macht davon gebrauch, aber ich empfehle es sonst niemanden.
Selbst wenn man nach dem Aufruf das Objekt nicht mehr benutzt, hat man ein Problem. Wenn der Speicher frei gegeben wird, ruft der Compiler des Destruktor noch mal auf, was in der Regel schief läuft.
Ein expliziter Destruktoraufruf gibt den Speicher nicht frei.
Beispiel:
{ MyClass myObject; myObject.~MyClass(); // hier wird der Destruktor explizit aufgerufen } // hier verläßt myObject seinen Scope, was bewirkt, daß der Destruktor noch mal aufgerufen wird und dann der Speicher frei gegeben wirdUnd jetzt das ganze auf dem Heap:
{ MyClass* myObjectPtr = new MyClass(); myObjectPtr->~MyClass(); // des Destruktor wird aufgerufen, aber der Speicher wird nicht frei gegeben! delete myObjectPtr; // der Destruktor wird nochmals aufgerufen und dann der Speicher frei gegeben }Lasse ich das "delete myObjectPtr" weg, wird zwar der Destruktor aufgerufen, aber es bleibt ein Memoryleak!

Hier wird es richtig gemacht (denke ich - ich würde so etwas nie machen):
{ MyClass* myObjectPtr = (MyClass*)malloc(sizeof(MyClass)); myObjectPtr->MyClass(); // Konstuktor aufrufen myObjectPtr->~MyClass(); // Destruktor aufrufen free(myObjectPtr); // und Speicher wieder frei geben }Ich hoffe, daß das letzte Beispiel auch den letzten davon abschreckt, den Destruktor explizit aufrufen zu wollen

Tntnet
-
Man kann (muss imho sogar) den Destruktor selbst aufrufen wenn man die Instanz mit Placement-new erzeugt hat, z.B. weil man einen 100 char großen Speicherbereich allokiert und dort 10 x 10 Byte Objekte angelegt hat. Hier müsste man zum Schluss 10x den Destruktor aufrufen und dann die 100 Byte am Stück wieder deallokieren.
#include <new> struct X { int y; }; int main(int argc, char* argv[]) { char mem[100]; X *ary = (X*) mem; new (ary + 0) X; new (ary + 1) X; new (ary + 2) X; /* ... */ /* delete[] ary geht schlecht, da der Speicher auf dem Stack liegt */ (ary + 0)->~X(); (ary + 1)->~X(); (ary + 2)->~X(); /* ... */ }EDIT:
Zu lahm
-
Mein erster Post hat doch alles beantwortet?! Nochmal, du musst nichts tun, das Objekt wird am Ende des Gültigkeitsbereiches automatisch zerstört und der Speicherplatz freigegeben. Nur wenn du das Objekt mit new allokiert hast musst du es manuell mit delete wieder freigeben.
/edit. Mkay, zu spät ...
-
Nur als Berichtigung. Wie LordJaxom schon sagte braucht man direkte Destruktor-Aufrufe bei Objekterzeugung durch placement new. Deswegen muß man bei tntnets Code den Konstruktor-Aufruf (der so nicht funktionieren würde) auch durch ein placement new ersetzen.
Also:MyClass* myObjectPtr = (MyClass*)malloc(sizeof(MyClass)); new (myObjectPtr) MyClass(); // Konstuktor über placement new aufrufen myObjectPtr->~MyClass(); // Destruktor aufrufen free(myObjectPtr); // und Speicher wieder frei geben