Zeiger-Problem



  • so, eine frage:

    das folgende proggi stürzt in der main-funktion ab. ("Couldn't do "write"-command at 0xbffff1c...")

    void Funktion(void)
    {
         int i = 0;
         int *ptr = &i +2;
    
         *ptr += 3;
    }
    
    int main(void)
    {
         int i = 0;
    
         Funktion();
         i = 1;     // <- hier/da kommt es zum absturz!
         cout << i << endl;
    
     return 0;
    }
    

    und warum stürzt es nicht ab, wenn ich als letzte zeile in Funktion()

    ptr = &i;
    

    hinzufüge? der zeiger wird doch schließlich in jedem fall gelöscht, bei der rückkehr.

    mfg



  • Standard-C++-Antwort: Undefiniertes Verhalten in Funktion().

    In Anbetracht deines Namens spekuliere ich aber mal, dass du absichtlich die Rücksprungadresse auf dem Stack um 3 Bytes erhöht hast, so dass der RET-Befehl, der Funktion() abschließt, in der main() die Anweisung i=1; nicht genau trifft, sondern irgendwie mitten rein platzt. Das genaue Verhalten kann man nur erklären, wenn man den compilierten Maschinencode kennt.

    und warum stürzt es nicht ab, wenn ich als letzte zeile in Funktion()

    ptr = &i;
    

    hinzufüge? der zeiger wird doch schließlich in jedem fall gelöscht, bei der rückkehr.

    Wahrscheinlich verteilt der Compiler die Variablen von Funktion() in beiden Versionen unterschiedlich zwischen Register und Stack, so dass das Stacklayout anders ist. Rein theoretisch könnte er Funktion() sogar komplett wegoptimieren (sogar wenn man mal davon absieht, dass er aufgrund des Undefinierten Verhaltens sowieso tun und lassen kann was er will) 😉



  • Liegt der Fehler nicht eher hier:

    int *ptr = &i + 2;
    


  • Ich glaube das Problem ist, dß Du einfach an eine 'wilde' Adresse einen Wert schreibst.
    Das Problem liegt nun darin, dass Dein Programm diese Adresse scheibar schon benutzt.

    Wenn Du Deinen Quellcode so umbaust, sollte es gehen, auch wenn es Nonsens ist.

    int main(void) 
    { 
      Funktion(); 
      int i = 0; 
      i = 1;
      cout << i << endl; 
      return 0; 
    }
    

    Von Adressen, die man sich nicht selbst geholt hat, oder das Programm dazu veranlasst hat sie zu holen, Finger weg. Meistens (eigentlich fast immer) geht das schief.



  • @CarstenJ:
    Wie Bashar schon angemerkt hat kann man aus dem Namen schließen, dass das gewollt ist. bufferoverflow-user hat lediglich übersehen, das heutige Compiler nicht mehr ganz so dämlich sind und den Code auch optimieren, weshalb sein Versuch in die Hose gegangen ist.

    Ich glaube das Problem ist, dß Du einfach an eine 'wilde' Adresse einen Wert schreibst.

    @dashi: Nein er glaubt schon eine bestimmte Adresse zu beschrreiben, die er sich vermutlich aus irgendeinem alten Tutorial gesucht hat.



    1a. ich weiß immer, wo meine zeiger gerade darufzeigen.
    1b. ich weiß immer, wo meine zeiger gerade draufschreiben.
    🙂
    2.

    Ich glaube das Problem ist, dß Du einfach an eine 'wilde' Adresse einen Wert schreibst.

    die Rücksprungaddresse liegt immer relativ gleich weit weg. jedenfalls, im moment noch...vielleicht sieht das bei der nächsten compiler-version wieder ganz anders aus :o (oder beim nächsten windows 😃 )

    danke für die antworten.

    mfg


Anmelden zum Antworten