delete von klassenvariablen
-
Warum geht denn das folgende nicht ohne speicherleck:
Index_Set *a = NULL; delete a; Index_Set::Index_Set(int len_a) { idcs = NULL; len = len_a; idcs = new int[len]; } Index_Set::~Index_Set() { if(idcs) delete [] idcs; } // idcs sind als member : int * idcs;
-
Ehm
Index_Set *a = NULL; delete a;Löschen eines Null-Zeigers. Kein Problem
Darfst a nur nicht dazwischen nutzen!Index_Set::Index_Set(std::size_t len) : m_len(len) { m_idcs = new int[len]; }geht auch
len muss aber positive Ganzzahl sein. D.h. std::size_t ...Index_Set::~Index_Set() { delete [] m_idcs; }NULL-Zeiger führen nicht zu undefiniertem Verhalten. Das ist auch i.O.

=>Sollte d.h. so gehen
-
gast_xy schrieb:
Warum geht denn das folgende nicht ohne speicherleck:
In dem Codestück passiert garnichts... Wo siehst Du ein Speicherleck?
-
Kann es sein, dass das am pointer liegt?
so lösche ich doch nur den pointer, nicht aber die member oder? Natürlich sind die Member gefüllt vorher. Wie lösche ich denn die member von Index_Set ohne lecks wenn ich sowas habe?Index_Set* a = NULL; Index_Set* b = NULL; b = new Index_Set(5); b->idcs[0] = 0; //fülle b weiter a = b; //hier verursacht ein delete a Probleme? Evtl. weil nur der Pointer gelöscht wird? delete a;
-
Du löscht niemals Pointer. Du löscht immer ein Objekt, dessen Adresse in einem Pointer gespeichert ist. Wenn das Objekt gelöscht wird, werden natürlich der Destruktor und die Destruktoren aller Mitglieder des Objekts auch aufgerufen.
Wenn Du Zeiger im Objekt hast (wie idcs), musst Du diese selbst verwalten, sprich löschen wie in Deinem vorletzten Beispiel mit delete im Destruktor. Damit sollte Dein Code keinerlei Probleme machen.
-
Index_Set* a = NULL; // a zeigt nirgendwo hin (0) Index_Set* b = new Index_Set(5); // b zeigt auf ein Index_Set-Objekt auf dem Heap a = b; // a zeigt auf das Index_Set-Objekt auf das auch b zeigt. delete a; // Das Index_Set-Objekt auf das a und b zeigen wird gelöscht. ({ ~dtor }) // !!! ACHTUNG !!! // b zeigt auf den nicht mehr existierenden Bereich aufm Heap ...
-
Also langsam verzweifle ich:
bevor ich etwas ändere, habe ich wirklich ein speicherleckfreies programm.
Sobals ich NUR diesen destruktor reinbaue OHNE dass er aufgerufen wird. Es wird immer noch Index_Set::Delete_Index_Set(Index_Set* is) aufgerufen!!!
Aber so bekomme ich 8000 errors:Index_Set::~Index_Set() { if (idcs) delete [] idcs; }Ich initialisiere meine Index_Set pointer nur so:
Index_Set * a = NULL; a = new Index_Set(...); //Mein Konstruktor: Index_Set::Index_Set(int len_a) { idcs = NULL; len = len_a; idcs = new int[len]; }das kann doch nicht sein

-
er schreit mit:
Conditional jump or move depends on uninitialised value(s) ==9597== at 0x8052FAA: Index_Set::~Index_Set() ....in..
-
ok es liegt an folgender sache:
Index_Set** j_sets; //j_sets wird initialisiert Index_Set *a = NULL; a = new Index_Set(3); j_sets[0] = a; Index_Set *b = NULL; b = j_sets[0]; //das folgende delete geht nicht mehr ohne probleme - WARUM? delete b;
-
Ehm sollte vorher schon raushauen ^^
Index_Set** ptr_array_set = new Index_Set*[1]; // !!! Muss schon auf was zeigen ;) !!! Index_Set* ptr_a = new Index_Set(3); ptr_array_set[0] = ptr_a; Index_Set* ptr_b = ptr_array_set[0]; delete ptr_b; ptr_b = NULL; // s.u. ptr_a = NULL; // damit man nicht mehr in Versuchung kommt ptr_a zu nutzen :P delete [] ptr_array_set; // muss auch wieder freigegeben werden!
-
Ich bin schon ganz balabala...
warum geht dann folgendes nicht und wie kann ich es lösen?:
Index_Set * a = NULL; for ( int i = 0; i < 5; i++) { //Get_Index_Set funktioniert !!!! a = Get_Index_Set(...); //mache was mit a if (//some_condition) break; delete a; } //hier muss das delete weg - aber wenn die break anweisung kommt //kann ich nicht einfach hier das delete hinmachen anstatt vor die break-anweisung? delete a;
-
Der Teil ist korrekt ... Get_Index_Set aber nicht
Index_Set * a = NULL; for (std::size_t i = 0; i < 5; ++i) { a = get_index_set(...); if ( ... ) break; delete a; } delete a; // delete NULL ist definiert....
-
so gehts - aber WARUM denn?
Index_Set * a = NULL; for ( int i = 0; i < 5; i++) { //Get_Index_Set funktioniert !!!! a = Get_Index_Set(...); //mache was mit a if (//some_condition) { delete a; break; } delete a; }get_index_set sieht so aus:
Index_Set* Class:Get_Index_Set(int i)
{
Index_Set * is = NULL;//is wird geholt // so ungefähr aber korrekt:
is = j_sets[i];return is;
}
-
Es lag doch an was ganz anderem . Ich habe auch Objekte so initialisiert:
Index_Set o_is;
nach dem fkt-scope wird da ja auch der destruktor aufgerufen der ja idcs löscht.
Da aber o_is den standard-konstruktor aufruft der leer ist bei mir, wird auch kein idcs initialisiert
Oh man....sein ein mist....
danke für die geduld und Hilfe.
-
Index_Set* Class::Get_Index_Set(std::size_t i) const { return j_sets[i]; }...
Index_Set* ptr = NULL; for (std::size_t i = 0; i < 5; ++i) { ptr = get_index_set(...); if (/* ... */) break; delete ptr; ptr = NULL; } delete ptr;sollte gehen ...
-
Ehm...da frage ich mich gerade wie mann denn dann für statische Objekte einen Konstruktor-Aufruf vermeiden kann aber damit auch nicht die Member im destruktor nach dem function-scope nicht gelöscht werden - gäbe ja einen seg-fault.?
Also wenn ich folgendes habe:
class A { public: A() { }; A(int num); ~A(); int * a; }; // implementierung A::A(int num) { a = new int[num]; } A::~A() { delete [] a; }Wie sollte denn sowas dann gehen?
//irgendwo: void B::fct() { A o_a; //nach dem verlassen gibts doch hier nen seg-fault //aber wie sollte ich dann statsiche objekte initialisieren? // So müsste ich ja immer das hier schreiben: int dummy = 0; A o_a = A::A(dummy); }Oder verstehe ich da irgendwas nicht so ganz?
-
Was meinst du mit statischen Objekten? Und was versprichst du dir von
A o_a = A::A(dummy);?
-
gast_xy schrieb:
Oder verstehe ich da irgendwas nicht so ganz?
Scheinbar. Fang besser nochmal ganz vorne bei Lebensdauer und Scopes an. Denn Deine Fragen sind konfus und ergeben sehr wenig Sinn.
-
Ok,
ich versuche die Erklärung nochmals:
Ich habe eine KLasse die so aussieht:
Index_Set::Index_Set(int len_a) { idcs = NULL; len = len_a; idcs = new int[len]; } Index_Set::~Index_Set() { if(idcs) delete [] idcs; }Jezt würde ich aber gerne sowas machen:
void Class::function() { Index_Set is; //hier mache ihc was mit is z.B sowas oder was anderes is.function(); }in der function() wenn die verlassen wird, wird doch automatisch der destruktor für is aufgerufen. Da is aber keinen idcs - pointer hat gibt es doch
einen seg-fault oder nicht? Schließlich passiert im default-konstruktor gar nichts, aber im "default-destruktor" wird auf idcs zugegriffen.Meine Frage war nun: Wie könnte ich das trotzdem bewerkstelligen dass ich is so anlegen könnte wie in function(). Oder macht das so sowieso keinen Sinn?
Müsste ich dazu evtl. den default-konstuktor noch umschreiben? Dann müssten aber solche Objekte immer erst alle member initialisieren bevor man sie aufrufen kann - ist das üblich?Danke für eure Hilfe
-
Du solltest einfach im Default-Konstruktor die/den Zeiger auch auf NULL setzen, dann wäre das gegessen

Und bei dem hieridcs = NULL; len = len_a; idcs = new int[len];kannst du das obere "idcs = NULL;" streichen, wird ja weiter unten sowieso mit einer "richtigen" Adresse belegt.
Edit: Und natürlich hat "is" in deinem Fall immer einen idcs-Pointer, nur der zeigt nirgendwohin. Also sollte der Wert des Zeigers NULL sein, denn darauf fragst du im Destruktor ja auch ab!