Überlauf von Variablen



  • Hi zusammen!

    Ich bin ein absoluter Anfänger und erkenn einfach nicht nach welchem Prinzip die Variablen überlaufen. Hab da so en Beispiel aus nem Buch:

    //Fehler2.cpp
    
    #include <iostream.h>
    
    void main()
    {
    	signed short int a = 10000;
    	signed short int b = 5;
    	signed short int value = 0;
    
    	value = a * b;
    
    	cout << "Werte der Variable: " << 
    		value << endl;
    }
    

    Als Ausgabe erscheint -15635

    Nun weiß ich aber nicht warum gerade dieser Wert erscheint, da der maximale Wert von

    unsigned short int
    

    doch bei 65535 liegt. Nach Erklärung des Buchs wär ein Überlauf so zu verstehen, dass wenn der max. Wert erreicht ist und 1 addiert wird nicht 65336, sondern 0 als Ergebnis ausgegeben wird. Wieso bin ich dann bei dem Beispiel im Negativen?

    Thx für alle Antworten!

    MfG
    Invisible



  • du hast signed short int und nich unsigned geschrieben - da wird das erste (?) bit als vorzeichen interpretiert



  • 32767 ist das Limit.



  • nur mal so für mich: schreibt man eigentlich noch void main() ? also dev cpp gibt dann einen fehler aus. ich nutze immer int main()



  • Tiffyrules schrieb:

    nur mal so für mich: schreibt man eigentlich noch void main() ? also dev cpp gibt dann einen fehler aus. ich nutze immer int main()

    In der FAQ gibt es einen Beitrag dazu. Er beantwortet dir deine Frage 🙂



  • freaked schrieb:

    Tiffyrules schrieb:

    nur mal so für mich: schreibt man eigentlich noch void main() ? also dev cpp gibt dann einen fehler aus. ich nutze immer int main()

    In der FAQ gibt es einen Beitrag dazu. Er beantwortet dir deine Frage 🙂

    kk, besten dank. nächstes mal schaue ich dort erst 🙂



  • Erstmal thx für die Antworten! Aber wenn ich jetzt 32767 und die 15635 zusammenzähl, kommt ja 48402 raus. Irgendwie versteh ich nicht wieso da gerade -15635 rauskam. Kann mir das bitte nochmal jemand erläutern?



  • Wenn ich dir den Tipp gebe, dass 32767 (höchste speicherbare Zahl) + 1 = -32768 (niedrigste speicherbare Zahl) ist, kommst du bestimmt selbst drauf 🙂



  • Sry, tut mir leid aber es scheint so als wär ich zu blöd...



  • PS: Ich weiß nur, dass ich das short int durch das long int ersetzen kann, aber nicht wie man auf die -15635 kommt 😕



  • Weil es sich um die gleichen hex-Werte handelt, die unterschiedlich interpretiert werden - jenachdem, ob gesagt wird, dass dieser Wert auch negativ werden kann oder ob dieser Wert nur positive Werte haben kann. NB: Dieser Bufferunderflow gehoert auch zu den typischen Gruenden fuer Sicherluecken in C/C++.



  • signed short:
    
    0x0000 = 0
    0x7FFF = 32768
    ------
    0x8000 = -32768
    0xc000 = -16384
    0xc350 = -15535
    0xFFFF = -1
    
    unsigned short:
    
    0x0000 = 0
    0xFFFF = 65535
    

    Im Hexadezimalsystem werden die Zahlen nicht nach signed und unsigned unterschieden, weil das nur eine Interpretation des Hex-Wertes in der Dezimaldarstellung ist. Die Zahl 50000 entspricht Hexadezimal 0xC350 und das wird als negative Zahl interpretiert. Bei vorzeichenbehafteten Zahlen findet ein Überlauf also bereits statt, wenn der Wert 0x7FFF übersteigt, da dann die Zahl vom positiven in den negativen Bereich umschlägt.



  • MBCS-CITP schrieb:

    NB: Dieser Bufferunderflow gehoert auch zu den typischen Gruenden fuer Sicherluecken in C/C++.

    in c? kann sein.
    in c++ sicher nicht.
    wer benutzt denn short für größenangaben? danger-seekers?
    außerdem ist das kein bufferunderflow.
    komisch, was du so erzählst.
    könntest du die quelle deines erstaunlichen wissens über "bufferunderflows" und "C/C++" preisgeben?



  • volkard schrieb:

    MBCS-CITP schrieb:

    NB: Dieser Bufferunderflow gehoert auch zu den typischen Gruenden fuer Sicherluecken in C/C++.

    in c? kann sein.
    in c++ sicher nicht.
    wer benutzt denn short für größenangaben? danger-seekers?
    außerdem ist das kein bufferunderflow.
    komisch, was du so erzählst.
    könntest du die quelle deines erstaunlichen wissens über "bufferunderflows" und "C/C++" preisgeben?

    Er wird wohl das hier meinen:

    char *buf = new char[256];
    
    	for (signed char i=0;i<256;i++) {
    		buf[i] = 0xA4;
    	}
    

    Aber Programmierfehler dieser Art sollten ja nicht allzu häufig auftreten.



  • volkard schrieb:

    in c? kann sein.
    in c++ sicher nicht.
    wer benutzt denn short für größenangaben? danger-seekers?
    außerdem ist das kein bufferunderflow.
    komisch, was du so erzählst.
    könntest du die quelle deines erstaunlichen wissens über "bufferunderflows" und "C/C++" preisgeben?

    Das Problem besteht nicht nur fuer "short", sondern auch fuer jeden andern unsigened/signed Datentype (size_t ist z. B. als solcher meisten implementiert; bei meinem 32-bit System z. B. als unsigned int). Wenn ich unsigned und signed mische (z. B. per int auf Adressen zugreife und diese um 1 erhoehe, wenn ich INT_MAX erreicht greife ich dann am -(INT_MAX - 1) (INT_MIN) zu). Das kann schon bei einer ungeschickten implentierung von char passieren.



  • Es ist eigentlich ganz einfach. Im Computer hat man keine Zahlen die auf einer geraden Linie dargestellt werden sondern auf einem Kreis. Also wie bei Winkeln. Da gilt auch 359° + 1° = 0° oder auch 180° + 1° = -179°. Im Computer hat man für jeden Winkel genau eine Zahl, also entweder 360° oder 0° aber nicht beides. Der Unterschied zwischen unsigned und signed ist legentlich, dass die eine von 0° bis 359° geht und die andere von -180° bis 179°.


Anmelden zum Antworten