new??



  • int* f(int z){
         int x[1];
         x[0]=z;
         return x;
    }
    
    int main()
    {
          int *x ;
          int *y;
          x = new int;
          y = new int;
          x = f(3);
          y = f(4);
          return 0;
    }
    

    Ausgabe:
    x: 0x241ff2c *x: 4
    y: 0x241ff2c *y: 4272168

    wieso haben x und y die gleiche Adresse?
    und wann ist es eigentlich sinvoll Zeiger mit new zu erzeugen?



  • Der Quelltext hat undefiniertes Verhalten. Das erkennst Du ganz einfach daran, dass eine Ausgabe erscheint, obwohl das im Quelltext niemals angeordnet wird.

    Wann gibst Du die 'Adressen' der Zeiger aus? warum gibst Du ein automatisches Feld aus einer Funktion zurück?



  • ich habe die cout-Zeilen einfach bloß weggelassen, damit der Text kürzer ist.
    Im eigentlichen Programm steht natürlich: cout <<"x: "<<x<<" *x: "<<*x<<endl;



  • int* f(int z){ 
         int x[1]; 
         x[0]=z; 
         return x; // Was soll das?
    } 
    
    int main() 
    { 
          int *x; 
          int *y; 
          x = new int; 
          y = new int; 
          x = f(3);      // Aha. Wenn du die Adressen überschreibst, wo bekommst du sie wieder her, um Sie zu deleten?
          y = f(4); 
          return 0; 
    }
    


  • danuel schrieb:

    Im eigentlichen Programm steht natürlich: cout <<"x: "<<x<<" *x: "<<*x<<endl;

    Im Programm also. Ich nehme mal an, Du meinst in der Funktion 'main'. Also:

    int main()  
    {  
          int *x;  
          int *y;  
            /* a) hier */
          x = new int;  
          y = new int;  
            /* b) hier */
          x = f(3);
          y = f(4);  
            /* c hier */
          return 0;  
    }
    

    a) Hier zeigen die Zeiger zufällig irgendwo hin.
    b) Hier zeigen beide Zeiger auf je einen Integer (vorausgesetzt alles geht gut und es fliegt keine Exception). Hier sind die Ausgaben garantiert nicht gleich .
    c) Hier wird auf die 'Adresse' des ersten Elements eines Feldes einer anderen Funktion gezeigt. Diese 'Adressen' können gleich sein, oder auch nicht. Auf jeden Fall sollten die Zeiger nicht dereferenziert (oder anderweitig gelesen) werden, wie Du es bei der Ausgabe tust. Außerdem hast Du keinen Zugriff mehr auf die Integer von oben, Du kannst sie nicht mehr löschen, der Speicher wird idR weiterhin als reserviert betrachtet, bis das Programm terminiert (oder auch manchmal länger: 'Memory Leak').

    Die restlichen Möglichkeiten wurden ignoriert.



  • beim aufruf der funktion f wird auf dem stack ein frame fuer f angelegt, der unter anderem das feld int x[1] beinhaltet. dieses feld hat eine addresse auf dem stack, diese addresse gibst du dann zurueck. jetzt wird die funktion f zweimal von dem selben level aus aufgerufen. es wird fuer den ersten aufruf eine frame fuer f angelegt, der beim beenden von f wieder bereinigt wird. wenn du direkt danach die funktion f wiederholt aufrufst wird der das neue frame von f natuerlich an die selbe stelle geschrieben wie das vorherige frame, damit ist x an der selben position.

    das was an der position x steht ist aber nicht wirklich definiert, wenn du zum beispiel eine weitere funktion aufrufst, dann wird an dieser stelle ein neuer frame stehen in dem auch wieder werte zugewiesen werden.

    ps: wenn man eine funktoion t schreibt, mit

    int* t(int i) {return f(i);}
    

    wird man nicht 2 mal den selben wert bekommen wenn man erst f(3) und dann t(7) aufruft. (ausgenommen der compieler wuerde das raus optimieren)


Anmelden zum Antworten