Nochmal CObArray
-
Guten Morgäänm,
da ich meine Problem von gestern immer noch nicht gelöst habe, hier mal eine Verständisfrage um auf die Sprünge zu kommen:
Wenn ich ein CObArray aus Objekten erzeuge läuft das ja so
CObArray oaTest; CMeinObject pObject = new CObject(......); oaTest.add(pObject); //So weit so gut //Kann ich jetzt um spätere MemoryLeaks zu umgehen den //Pointer gleich wieder löschen (hat das Array also ein Kopie) //oder nur einen Zeiger gespeichert delete pObject;
Geht das so, oder bekomme ich später wenn ich auf das Array zugreife fehler?
-
Du hast einen Zeiger auf das Objekt gespeichert.
Löscht du also dieses mit delete dann gibt es beim nächsten Zugreifen einen Fehler.Um Memoryleaks zu umgehen könntest du dir eine Klasse von CObArray ableiten und im Destruktor einfach alle Objekte löschen.
-
Das habe ich ja bisher auch gedacht. Das Problem ist nur, dass ich aber trotzdem auf den Array nach dem delete zugreifen kann, und auch die Daten auslesen kann (indem ich das Object wieder caste...)
.... delete pMeinObject; ... CMeinObject *pMeinObject = (CMeinObject*) oaTest[0];
Das Funkioniert direkt nach dem ich das delete ausgeführt habe. Aber warum???
-
Du greifst ja auch nicht auf die Membervariablen zu.
Versuch mal:
MyObject* obj = new MyObject; delete obj; obj->memberVar = 2;
-
Jaja, das ist mir ja schon klar, deshalb ging ja meine spezielle Frage an den CObArray. Weil dort funkioniert das ja komischer weise, d.h. muss ja heisen das in dem Array die Objekte kopiert werden....
Nochmal der ganze Code, das wir uns nicht falsch verstehen:
CObArray oaTest; CMeinObject pObject = new CObject(......); oaTest.add(pObject); //Hier wird der Zeiger auf das mit new erstellte Object gelöscht. delete pObject; //Und hier hole ich mir wieder zugriff auf das Object. Also muss //das Object ja im Array gespeichert sein und nicht nur der Zeiger... CMeinObject *pMeinObject = (CMeinObject*) oaTest[0]; int iTest = pMeinObject->m_iTest;
Der Zugriff auf die Membervariablen im den Object funktioniert nämlich auch...
-
Du kannst auch
int x = reinterpret_cast<MyObject*> (12321100)->val;
schreiben.Er holt dann halt von der Adresse den Wert von val.
Entweder gibt es dann eine Access violation oder es passiert nix.
Du greifst dann halt auf Speicher zu den du nicht angefordert hast.
Wenn du einen Wert schreibst kann dann halt mehr schief gehen.reinterpret_cast<MyObject*> (12321100)->val = 222;
-
Danke aber nochmal zu meiner Frage. Kann ich den Zeiger jetzt löschen, ohne das ich irgendwann im Prog mal eine Zugriffsverletztung bekomme, oder muss ich Ihn stehen lassen, und irgendwann am Ende löschen. Was ist den der saubere Weg?
-
Man löscht ihn selbstverständlich dann erst wenn er nicht mehr benötigt wird.
Speicher den du nicht angefordert (oder wieder freigegeben) hast nutzt man nie (Ausser die lieben Bugs...). Wie gesagt: Würde ich im Destruktor machen.
btw: Du kannst auch die Template-Klasse CArray (-> afxtempl.h) nehmen. Dann ersparst du dir das casten.
-
Vielleicht sollte hier auch mal klar gestellt werden, dass Zeiger NICHT gelöscht werden können. Der Zeiger zeigt (daher ja auch der Name) nur auf das per new erzeugt Objekt. Mit delete wir das Objekt gelöscht. In bestimmten Fällen lässt sich danach immer noch über das CObArray auf die Daten zugreifen, so lange sie nicht überschrieben wurden. Der Zeiger kann nach dem Aufruf von Add() auf NULL gesetzt werden oder anderweitig verwendet werden. Das Objekt besteht dann immer noch, muss natürlich vor dem Programmende gelöscht werden. CObArray hat also KEINE Kopie.
-
was heist den nun in bestimmten Fällen? Soll ich nun die delete-Anweisung stehen lassen, oder muss sie weg?
-
Also, wenn Du ein Objekt mit new erstellst und in ein CObArray per Add() einfügst und dort auch weiter verwendest, dann solltest Du tunlichst das delete entfernen, ansonsten bekommst Du ein "Memory Access Violation" oder irgendetwas anderes. Denn CObArray hält auch nur einen Zeiger auf das Objekt, keine Kopie! Also würde ein Aufruf von delete das Objekt löschen, aber CObArray zeigt noch immer auf die Speicherstelle -> GAR NICHT GUT! Um mal mit Metaphern zu sprechen: Wenn Du jemandem Deine Postadresse mitteilst (add()) und dann stirbst (delete), dann geht die Post von demjenigen auch ins Leere.
Wenn das Objekt dann irgendwann per delete gelöscht wird, dann auch aus dem CObArray entfernen, ansonsten gibt's wieder Fehler!
Also zusammenfassend: delete wegnehmen sonst Ärger!