Verständnisproblem Adressoperator



  • Hallo zusammen,

    folgendes Verhalten:

    In main:

    Foo bar(0,0,0);
    doSomething(&bar);
    

    in der Funktion mache ich folgendes:

    void doSomething(Foo *bar) {
    bar = new Foo(2,2,2);
    }
    

    Zurück in main hat bar weiterhin die Werte 0,0,0.
    Was mache ich falsch?

    👍



  • leider ziemlich viel...

    Foo bar(0,0,0);
    doSomething(bar);
    

    und

    void doSomething(Foo &bar)
    {
     bar = Foo(2, 2, 2);
    }
    

    ODER

    Foo bar(0,0,0);
    doSomething(&bar);
    

    und

    void doSomething(Foo *bar)
    {
      assert(bar);
      *bar = Foo(2, 2, 2);
    }
    

    ODER

    Foo *bar;
    doSomething(bar);
    

    und

    void doSomething(Foo *&bar)
    {
      assert(bar);
      bar = new Foo(2, 2, 2);
    }
    

    aber dann nicht vergessen, delete wieder aufzurufen...

    ich würde die erste möglichkeit wählen, wenn du nicht auf den freispeicher(heap) angewiesen bist...

    bb



  • Du unterscheidest offensichtlich nicht zwischen "pointer" und "pointee".

    &bar liefert dir einen Zeiger. Dieser Zeiger wird als Wert an die Funktion übergeben. Hierbei wird eine lokale Zeigervariable erzeugt, die unglücklicherweise auch "bar" heißt. In der Funktion wird diese Zeigervariable mit einer neuen Adresse überschrieben. Die Zeigervariable hört wieder auf zu existieren und Du hast ein Speicherleck.

    Versuch's nochmal.



  • Danke Jungs, jetzt hab ichs geschnallt!
    Vorallem "unskilled" ein herzliches Dankeschön für die schnelle und ausführliche Antwort!



  • unskilled schrieb:

    void doSomething(Foo &*bar)
    {
      assert(bar);
      bar = new Foo(2, 2, 2);
    }
    

    Da ist noch ein Dreher drin. Es muss & statt & heissen.
    :p 😉



  • Sebastian Pizer schrieb:

    unskilled schrieb:

    void doSomething(Foo &*bar)
    {
      assert(bar);
      bar = new Foo(2, 2, 2);
    }
    

    Da ist noch ein Dreher drin. Es muss & statt & heissen.
    :p 😉

    ach verdammt - ich werds mal ändern^^
    wie merkst du dir eigtl, wie rum es sein muss? ich weiß es jz sicherlich wieder paar wochen lang und dann muss ich das nächste mal wieder raten oder sagen, es war ein vertipper 😉

    bb



  • unskilled schrieb:

    wie merkst du dir eigtl, wie rum es sein muss? ich weiß es jz sicherlich wieder paar wochen lang und dann muss ich das nächste mal wieder raten oder sagen, es war ein vertipper 😉

    Das kannst du dir einfach merken, wenn du Typinformationen von rechts her liest:

    Foo    // Foo-Objekt
    Foo*   // Zeiger auf Foo-Objekt
    Foo*&  // Referenz auf Zeiger auf Foo-Objekt
    

    Ähnlich wie bei const .



  • Sprich es aus: Das ist eine Referenz auf ein Zeiger, andersrum wäre es recht komisch. 🤡



  • ah - ty :>



  • unskilled schrieb:

    wie merkst du dir eigtl, wie rum es sein muss?

    Du kannst solche Deklarationen wunderbar von "innen nach außen" lesen. Man muss sich nur merken, dass Postfix-Operatoren stärker binden als Präfix-Operatoren. Das & für Referenzen verhält sich wie ein Präfix-Operator.

    "bar ist eine Referenz auf Zeiger"

    Es hat aber eine Weile gedauert, bis ich das verinnerlicht hatte. 🙂

    Gruß,
    SP


Anmelden zum Antworten