Seiteneffekt (Wirkung)



  • Hallo zusammen,

    ich habe an meiner Hochschule folgende Aufgabe bekommen:

    Versuchen Sie die Ausgabe des folgenden Programmes zu begründen und erklären Sie, warum es verboten ist, Zeiger auf lokale Variablen als Funktionsergebnis zurückzugeben.

    #include<stdio.h>

    void foo(void)
    {
    int a = 2345;
    printf("In foo: &a = %p, Wert = %d\n\n", &a, a);
    }

    void bar(void)
    {
    int z;
    printf("In bar: &z = %p, Wert = %d", &z, z);
    }

    main()
    {
    foo();
    bar();
    }

    Als ich das Programm zunächst gelesen habe dachte ich auf jedenfall, dass die Ausgabe von a und z verschieden ist aber dem ist nicht so. Beide haben den selben Speicherplatz und den selben Wert (2345). Ich habe schon ein wenig im Internet recherchiert aber kann es mir irgendwie nicht erklären. Kennt sich jemand damit aus und kann mir helfen?

    Danke im Voraus



  • Weist du wie der Stack funktioniert und wie lokale Variablen darauf abgelegt werden?

    Da beide Funktionen fast gleich sind, liegen die Variablen an der gleichen Addresse (muss aber nicht immer so sein). Die Speicherstellen werden beim freigeben nicht geloescht.
    Den Rest ueberlasse ich dir.



  • Danke für die schnelle Antwort 🙂
    Ok habe mich gerade nochmal ein bisschen in die Funktionsweise von einem Stack eingelesen und folgendes gefunden:

    --------------------------------------------------------------------------------
    int f1(int wert, int *zeiger)
    {
    auto int add = 2; // "auto" ist unnötig
    int lokal = wert + add;
    zeiger = lokal;
    return 2
    lokal;
    }

    Bei jedem Aufruf von f1 wird eine neue Schicht (frame) auf den Stack gelegt. Sie enthält die lokalen Variablen (add, lokal), die mit den Argumenten initialisierten Parameter (wert, zeiger) und eine Rücksprungadresse, damit das Programm „weiß“, von wo die Funktion aufgerufen wurde. Wird die Funktion mit return verlassen, wird die Schicht vom Stack entfernt, die Variablen vernichtet und der Programmablauf bei der Rücksprungadresse fortgesetzt. Wohlgemerkt: Auch die Variablen wert und zeiger werden zerstört. Den Speicher, auf den zeiger zeigt, beeinflusst das nicht.
    --------------------------------------------------------------------------------

    Sooo, wenn ich das auf meine Aufgabe anwende verstehe ich nun, dass der Speicherplatz identisch ist. Allerdings ist mir noch nicht ganz klar, wie der Wert von a in die Variable z gelangt, wenn diese doch nach dem durchlaufen der Funktion gelöscht wird?? 😕



  • Geloescht heisst nicht, dass der Speicher mit beispielsweise Nullen ueberschrieben wird. Er wird lediglich freigegeben. Der vorher beanspruchte Speicherplatz ist nun also frei, kann verwendet werden, um neue Daten, eben zum Beispiel einen Frame zu speichern.

    Wenn dort aber nichts reingeschrieben wird, stehen an der Stelle im Speicher die alten Werte.

    Siehe auch

    #include<stdio.h> 
    
    void foo(void) 
    { 
        int a = 2345; 
        printf("In foo: &a = %p, Wert = %d\n\n", &a, a); 
    } 
    
    void bar(void) 
    { 
        int z = 0; // Achtung, Aenderung!
        printf("In bar: &z = %p, Wert = %d", &z, z); 
    } 
    
    main() 
    { 
        foo(); 
        bar(); 
    }
    


  • Skyfall91 schrieb:

    Sooo, wenn ich das auf meine Aufgabe anwende verstehe ich nun, dass der Speicherplatz identisch ist. Allerdings ist mir noch nicht ganz klar, wie der Wert von a in die Variable z gelangt, wenn diese doch nach dem durchlaufen der Funktion gelöscht wird?? 😕

    Wenn du nach der Pause in einen Klassenraum gehst, stehen auch noch die Sachen vom vorhergehenden Unterricht an der Tafel - obwohl der Raum frei ist.



  • Aaah ok so langsam verstehe ich das, danke euch allen! 👍



  • DirkB schrieb:

    Wenn du nach der Pause in einen Klassenraum gehst, stehen auch noch die Sachen vom vorhergehenden Unterricht an der Tafel - obwohl der Raum frei ist.

    Das ist mal eine gute Erklärung. Würde sogar ich verstehen.


Log in to reply