Verschachtelte Objectstrukturen mit Zeigern



  • HerbertB schrieb:

    D.h. ich lege den raw-pointer mit new an, füge ihn mit push_back in den ptr_container (z.b. boost ptr_vector) ein, und zerstöre anschließend den raw-pointer mit delete gleich wieder?

    delete zerstört nicht den Zeiger, sondern das Objekt, auf das der Zeiger zeigt.

    Mal eine kleine Analogie zum besseren Verständnis: (ich habe bewusst verzichtet, im folgenden Text C++-Ausdrücke wie delete, vector, pointer zu verwenden, wenn du ein wenig darüber nachdenkst, sollte es dir klar werden - ansonsten frag einfach)

    Stell es dir so vor: du hast ein wichtiges Dokument gut versteckt in deinem Schreibtisch. Weil es so wichtig ist, schreibst du dir auf einen Zettel, wo genau du das Dokument versteckt hast. Und weil du viele wichtige Dokumente versteckt hast, hast du auch viele Zettel. Diese sind alle säuberlich in einer Mappe eingeheftet. Jetzt hast du dein neues Dokument versteckt, und den Zettel mit dem Ort möchtest du auch einheften. Du kopierst dir den Zettel und heftest die Kopie in die Mappe. Anschließend zerreißt du das Original.

    Wenn du jetzt die Mappe verlieren solltest, sind die Dokumente zwar noch da, nur findest du sie nie wieder.

    Und wenn du ein Dokument vernichten willst, dann schaust du in der Mappe nach, wo sich das Dokument befindet und zerreißt das Dokument. Der Zettel mit dem Ort des Dokumentes ist dann zwar immer noch da, aber nutzlos.



  • Hmmm, ok, und wie sieht das abgebildet auf meinen beispielcode aus post 1 aus?

    Der vector ist die mappe, wo ich den kleinen zettel abhefte? Und der raw pointer ist das eigentliche dokument?



  • nagut, ich dachte, die Analogie wäre mit ein wenig Nachdenken erkennbar.

    du legst ein neues Dokument mit "new" an. Den Rückgabewert - die Adresse des Objektes - speicherst du in einem Pointer (der kleine Zettel). Bei push_back wird der Pointer kopiert, also hast du nun zwei Pointer, die auf ein Objekt zeigen. Mit delete löschst du das eigentliche Objekt (zerreißen des Dokumentes). Die Pointer existieren anschließend immer noch, nur sind sie nicht mehr verwendbar.



  • Hier sind Videos zur Zeigererklärung
    http://cslibrary.stanford.edu/104/



  • Ich komme von der java seite, und darum verwirrt mich das jetzt noch ein bisschen, aber ich glaube jetzt hab ichs.

    Ich habe ein objekt mit new angelegt, und die adresse steht im pointer, wenn ich jetzt push_back mache, habe ich einen zweiten pointer auf das gleiche objekt.

    Wenn ich das objekt zerstöre, zeigen beide pointer irgendwo hin --> undefiniertes verhalten.

    Mein problem:

    Ich habe die adresse auf ein objekt in dem raw pointer und ich habe die adresse auf ein objekt im vektor.

    Ich hole mir über die adresse aus dem vektor das objekt und zerstöre es mit delete, anschließend lösche ich die adresse aus dem vektor.

    Jetzt bleibt aber noch immer die adresse im raw-pointer, die ins nirgendwo zeigt.

    Was mache ich jetzt damit? Einfach NULL setzen? Oder wie werde ich den pointer los?

    @Braunstein

    Danke für die videos, aber die funktionieren bei mir nicht. Vielleicht leigt das am browser oder fehlenden codecs bei mir.



  • HerbertB schrieb:

    Ich habe ein objekt mit new angelegt, und die adresse steht im pointer, wenn ich jetzt push_back mache, habe ich einen zweiten pointer auf das gleiche objekt.

    Richtig.

    HerbertB schrieb:

    Wenn ich das objekt zerstöre, zeigen beide pointer irgendwo hin --> undefiniertes verhalten.

    Naja, zeigen dürfen sie schon darauf, sie dürfen nur nicht schreibend darauf zugreifen.

    HerbertB schrieb:

    Ich habe die adresse auf ein objekt in dem raw pointer und ich habe die adresse auf ein objekt im vektor.

    Ich hole mir über die adresse aus dem vektor das objekt und zerstöre es mit delete, anschließend lösche ich die adresse aus dem vektor.

    Jetzt bleibt aber noch immer die adresse im raw-pointer, die ins nirgendwo zeigt.

    Was mache ich jetzt damit? Einfach NULL setzen? Oder wie werde ich den pointer los?.

    Da kannst du nichts machen. Den Zeiger bekommst du erst am Ende des Gültigkeitsbereichs los. Du kannst also nur den Gültigkeitsbereich verkleinern.
    Natürlich kannst du ihn auch NULL-setzen. Aber was bringt dir das? Egal ob NULL oder nicht NULL, in beiden Fällen wirst du den Zeiger doch nicht mehr verwenden.



  • HerbertB schrieb:

    @Braunstein

    Danke für die videos, aber die funktionieren bei mir nicht. Vielleicht leigt das am browser oder fehlenden codecs bei mir.

    Du brauchst da wohl Quicktime dafür.



  • Java-Objektreferenzen sind vereinfachte Zeiger.



  • Ich glaub jetzt hab ich es verstanden.

    Abschließend noch, wenn ich mehrere zeiger auf ein objekt habe, das objekt aber dann zerstöre, ist der speicher wieder freigegeben und es entsteht kein speicherleck. Die zeiger darauf sind noch vorhanden, und verschwinden erst wenn der gültigkeitsbereich verlassen wird.

    Kann man eigentlich irgendwie überprüfen, ob das objekt auf das der zeiger zeigt, noch existiert?



  • HerbertB schrieb:

    Kann man eigentlich irgendwie überprüfen, ob das objekt auf das der zeiger zeigt, noch existiert?

    Nein, das musst du dir schon selber merken wenn du das wirklich brauchst.



  • Manche smart pointer können das, bspw. der QPointer aus Qt. Der setzt sich selbst auf NULL, wenn das enthaltene Objekt zerstört wurde.



  • Wenn man wirklich mehrere Zeiger auf ein Objekt benötigt, bieten sich shared_ptr und weak_ptr an. Die shared_ptr halten das Objekt am Leben, solange noch ein shared_ptr auf das Objekt zeigt, und die weak_ptr wissen, ob noch shared_ptr auf dieses Objekt zeigen (ergo ob das Objekt noch lebt).


Anmelden zum Antworten