Konstruktor / Destruktor
-
Hallo, ich habe folgenden struct um einen Baum zu bauen.
Der Konstruktor wird aufgerufen - der Destruktor aber nicht.
Ist er unnötig oder falsch?typedef struct node{ char *value; struct node* leftchild; struct node* rightchild; node(){ cout<<"Konstruktor"<<endl; value=new char[20]; } void get(){cout << value <<endl;} ~node(){ cout<<"Destruktor"<<endl; delete[] value; } } knoten;
-
ich vermute, dass du über new den knoten auf den freispeicher bringst..dann musst du auch den speicher wieder freigeben..
#include <iostream> using namespace std; typedef struct node{ char *value; struct node* leftchild; struct node* rightchild; node(){ cout<<"Konstruktor"<<endl; value=new char[20]; } void get(){cout << value <<endl;} ~node(){ cout<<"Destruktor"<<endl; delete[] value; } } knoten; int main(){ knoten *x=new knoten; delete x; //!!! }
-
es gibt eigentlich nur zwei Möglichkeiten, den Konstruktor aufzurufen ohne irgendwann bis zum normalen Ende des Programms den passenden Destruktor nicht zu rufen.
1.) Du machst ein placement new und hast das placement delete vergessen
2.) Du erzeugst ein Objekt dieser Klasse auf dem Heap und hast das delete nicht gemacht; mit anderen Worten: Dein Programm hat ein Memory-Leak.Deine Klasse hat einen nicht trivalen Destruktor aber keinen Copy-Konstruktor und Assign-Operator. Damit brichst Du die "Regel der 3"; wie sie z.B. in "C++ FAQs (Addison-Wesley 1998), by Marshall Cline, Greg Lomow, and Mike Girou" beschrieben ist.
"whenever you need either a (non-trivial) copy constructor, copy assignment operator, or destructor, you'll most likely need to implement the others, too."Noch ein Hinweis. Die Konstruktion:
typedef struct node { // ... } knoten;ist ein Erbe von C. In C++ ist folgendes üblich:
struct knoten { // ... };Gruß
Werner
-
Danke für die Hinweise!
@Werner: Dann wissen wir ja was mein Prof am liebsten Programmiert

Werde die gr. 3 das nächste mal beachten.@elise: Ja genauso mach ich das dann... aber auch bei "delete x;" wird nicht der Destruktor benutzt oder irre ich da?
Ich dachte man braucht einen Destruktor immer dann wenn man im Konstruktor etwas stehen hat das über die fundamentalen Typen hinausgeht. Zeiger zB.
-
sobald du mit new etwas anlegst, MUSST du SELBER darauf achten, dass der Speicher wieder freigegeben wird!!! Daher musst/solltest du das delete nutzen. Dieses wiederum ruft den Destruktor auf bei einem Objekt.
Wenn du keinen Destruktor definiert hast, wird vom Compiler ein Standarddestruktor erzeugt.
-
Das leuchtet ein.
Allerdings wird bei mir nicht "Destruktor" ausgegeben wenn ichdelete einKnoten;mache. Wenn ich
einKnoten.~node();aufrufe wird es schon ausgegeben. Wie funktioniert denn das?
-
wenn du
delete einKnoten;schreibst, sollte das in der regel dann auch ein pointer sein - allerdings weisst dein
einKnoten.~node();nicht darauf hin das dem so ist (.) .
-
Stimmt, da habe ich mich vertippt. Ich meine natürlich:
einKnoten->~node();Wenn ich den Destruktor so aufrufe gibt er wie geplant "Destruktor" aus, bei delete nicht...
-
nein, so ruft man an der stelle keinen destruktor auf.
zeig deine funktion mit den entsprechenden zeilen der instanziierung und das delete.
-
also den Destruktor selbst aufrufen, das sollte man im Normalfall nicht machen, nur so als Hinweis
-
Danke für eure Hilfe, jetzt funktioniert es wie erwartet.
Der Destruktor hat sich (so wies aussieht) nicht gemeldet weil ich in meinem Knoten zwar einen char[20] reserviert hatte aber dann nichts zugewiesen habe. Anscheinend muss dann der Destruktor nicht aufgerufen werden - wenn man was zuweist dann wird er jedenfalls aufgerufen.