Kleines sinnloses Programm welches den Speicher überschreibt



  • Hallo,
    wer Bashars Ausführungen bisher nicht verstanden hat, dem hilft vielleicht folgendes Programm auf die Sprünge:

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    int main()
    {
            char* p = malloc(1);
            char* q = p;
            while( *(p--) = '\0')
                    printf("In der Schleife!\n");
            assert(p == q-1);
            return 0;
    }
    

    Es wird ganz genau keinmal "In der Schleife!" ausgegeben. Zuerst wird die Zuweisung ausgeführt -> *p = '\0'.
    Dann wird die Zuweisung als boolescher Ausdruck für die Schleifenbedingung ausgewertet -> *p = '\0' = 0 = false. Die Schleifenbedingung ist also false und damit wird die Schleife nicht ausgeführt. Der Ausdruck ist aber noch nicht ganz zu Ende. Das postfix-decremennt wird auch noch ausgeführt. Das Ergebnis hat aber keinen Einfluss auf das Ergebnis der Zuweisung und damit keinen Einfluss auf die Schleifenbedingung.

    Das der Seiteneffekt tatsächlich stattfindet beweist das letzte assert.



  • @tobidope ist mir klar ich habs ja schon weiter oben erwahnt das ich mir das schlecht vorstellen kan. Ich kommentiere das gesagte. Und warum gehst du davon aus das wir hier von Win2000/xp ... reden.



  • Stimmt das mit dem Rückgabewert hab ich nicht bedacht, dachte der Ausdruck als
    solcher wird auf erfolg oder fehlschlag geprüft und dies verwendet.
    In Java ist das so, daher wohl der Irrtum.

    Dann war das mit dem PC wohl purer Zufall.



  • -SirLant- schrieb:

    In Java ist das so, daher wohl der Irrtum.

    Auch in Java ist das nicht so. Du bekommst eine Exception, wenn du eine Arraygrenze überschreitest.



  • Wär mir auch neu, dass das in Java so wäre...

    @Threadersteller
    So wird das sicher nicht hinhauen, auch wenn du die Schleifenbedingung richtig machst. Ich glaub, ich hab früher ab und zu meinen Rechner zum Absturz gebracht, wenn ich versehentlich auf die Speicheradresse 0 geschrieben hab oder eine der nachfolgenden. Allerdings bin ich mir nicht ganz sicher. Außerdem war das noch unter Win95. Bei neueren OS wie Windows 2000 oder XP bekommst wahrscheinlich einen Access Violation o. ä.

    @Bashar
    Warum ist das Verhalten nicht undefiniert??
    Er würde wahrscheinlich beim ersten nullsetzen wahrscheinlich den auf den Speicherbereich des Zeigers selbst schreiben, aber nur auf einen Teil. Zeiger sind doch normalerweise vom Typ unsigned int, oder?



  • AJ schrieb:

    @Bashar
    Warum ist das Verhalten nicht undefiniert??

    Lies das Programm nochmal. Es wird nur die Speicherstelle *p beschrieben, und das ist die, die gerade von malloc zurückgegeben wurde.



  • Wie wäre es dann damit:

    #include <stdlib.h>
    int main (void) {
      char *p = NULL;
      *p = 123;
      return 0;
    }
    

    Würde er dann hier abstürzen wenn ich das von euch richtig verstanden habe?



  • Das Verhalten ist undefiniert. Unter DOS wird wohl zunächst überhaupt nichts passieren, unter Linux kassierst du ein SIGSEGV.



  • Sorry -SirLant-, aber deine Programme sind absolut sinnlos. Desweiteren ist es absolut ausgeschlossen, dass dein Programm (das alleine von der Schleifenlogik schon nicht funktioniert) irgendwas böses angerichtet hat.

    Du hast bei heutigen Betriebssystemen KEINEN direkten Zugriff auf den gesamten Hauptspeicher (irgendwie ist auch der Gedanke absurd, dass ein einziges böswilliges Progamm den gesamten Speicher überschreiben kann).
    Dein Programm erhält bestimmte Segmente des HSP. Falls du versuchst, auf eine Adresse zuzugreifen, die nicht deinem Programm gehört, dann wird das BS dies unterbinden (es wird einfach dein Programm beenden).
    Direkte und restriktionslose Zugriffe auf die Hardware bleiben deinem BS vorbehalten (Stichwort: SVC)

    flo



  • @Bashar
    Ich meine, wenn die Schleife so funktionieren würde, wie es gedacht ist vom Ersteller, dann wäre das Verhalten doch undefiniert, oder?



  • Ja, wenn.


Anmelden zum Antworten