Speicher mittels free() freigeben; Verständnisfrage



  • Hi zusammen,

    dies ist mein erster Post und bestimmt nicht mein Letzter. Habe mich bereits umgeschaut und auch das FAQ zum Thema free() durchgelesen, nur leider beantwortet es nicht die Frage, die ich mir stelle.

    Ich bin ein C-Neuling und habe erst vor kurzen damit angefangen mich damit einzulesen. Ich bin grad bei Strukturen, wo ich eben jetzt eine Verständnisfrage hätte, die ich nirgends beantwortet bekomme.

    Hier erstmal ein kleiner Codeteil:

    #include <stdio.h>
    #include <stdlib.h>
    
    struct _CDouble_ {
          double a;
          double b;
          char* name;
    };
    typedef struct _CDouble_ cdouble;
    
    cdouble* newCDouble();
    
    main(){
           cdouble *var;
    
           var = newCDouble();
           printf("%f, %f, %s\n", var->a, var->b, var->name);
    
           free(var);
           printf("%f, %f, %s\n", var->a, var->b, var->name);
    
           var = newCDouble();
           printf("%f, %f, %s\n", var->a, var->b, var->name);
    }
    
    cdouble* newCDouble (){
           cdouble* strukt = malloc(sizeof(cdouble));
           strukt->name = "Karl";
           strukt->a = 2;
           strukt->b = 5;
    
           return strukt;
    }
    

    Wenn man dieses Programm ausführt, wird zuerst "var" mit Werten gefüllt und ausgegeben. Danach wird "var" mittels free() freigegeben (sollte meiner Meinung zumindest so sein) und wieder ausgegeben. Hier ist das Problem.
    Warum wird nur der 1. Wert auf 0 gesetzt und nicht das komplette?

    Ich habe auch schon gelesen, wenn man realloc verwendet und der erste Wert auf NULL gesetzt ist, entspricht es sozusagen einen malloc...
    Ist es dann so wie es jetzt ist, korrekt?

    Danke für die Infos 🙂

    lg 🙂



  • Das zweite printf bricht ab, da du hier nicht (mehr) gültige Speicherbereiche übergibst. Ab free ist der Speicher ungültig. Es fehlt auch ein free nach dem letzten printf.



  • Das nach dem letzten printf noch ein free() fehlt ist mir klar. Sollte eigentlich nur ein Test fürs Verständnis sein.

    Es bricht übrigens bei mir überhaupt nichts ab. Habe vergessen den Konsolenausgang zu posten, somit tu ich dies jetzt.

    Niedi@Niedi-PC ~/serie05
    $ a.exe
    2.000000, 5.000000, Karl
    0.000000, 5.000000, Karl
    2.000000, 5.000000, Karl
    

    Es wird alles ausgegeben, jedoch eben bei der zweiten Ausgabe, nur der 1. Wert auf 0 gesetzt.

    lg



  • Ich glaube das ist mehr oder weniger Zufall. free bedeutet nur dass der Speicher freigegeben ist, wenn man dann noch drauf zugreift ist das Verhalten undefiniert, d.h. es kann alles passieren



  • Und wo ist jetzt das Problem? Beim zweiten printf hast du undefiniertes Verhalten, das heißt es können die alten Werte drinne sein oder auch nicht oder was ganz anderes, es könnte auch das Programm abstürzen.

    Ralfi



  • linux_c89 schrieb:

    d.h. es kann alles passieren

    Aber am wahrscheinlichsten ist, dass dir ein Dämon aus der Nase fliegt. Und das tut weh!



  • ^^ Ich wollte eigentlich nur wissen, ob es so wie ich es geschrieben habe, eben dieses free(), korrekt ist 🙂 Ob somit der Speicherbereich freigegeben wurde.

    Oder ob ich eben jeden String explizit auf NULL und die Werte auf 0 setzen muss.

    Aber euren Posts nach, sollte es ja korrekt sein, bis auf das fehlende free() am Ende nach dem letzten printf 🙂

    Danke 🙂

    lg



  • Aber am wahrscheinlichsten ist, dass dir ein Dämon aus der Nase fliegt. Und das tut weh!

    Sagen wir mal so ein Compiler der das macht ist immer noch Standardkonform^^



  • Niedi schrieb:

    ^^ Ich wollte eigentlich nur wissen, ob es so wie ich es geschrieben habe, eben dieses free(), korrekt ist 🙂 Ob somit der Speicherbereich freigegeben wurde.

    ja und ja

    Niedi schrieb:

    Oder ob ich eben jeden String explizit auf NULL und die Werte auf 0 setzen muss.

    wozu solltest du das? ich verstehe nicht, woher dieses Aberglaube kommt, die struct-Member auf 0 setzen zu wollen/müssen bevor man free aufruft 😕

    free gibt dem Speicher frei, mehr nicht. Du musst aber nicht den Inhalt auf 0 setzen, das ist unnötig.

    Nach dem free darfst du auf den befreiten nicht mehr zugreifen, du weiß ja nicht, was damit passiert ist. Es kann alles mögliche passieren, du könntest sogar den dritten Weltkrieg damit starten. Willst du wirklich?

    3. NULL und 0 nicht miteinander verwechseln. NULL ist der NULL-Pointer, 0 ist die Zahl 0.



  • hi supertux.

    Vielen Dank für deine einleuchtende Antwort. Habs nun kapiert und werde es nicht mehr vergessen *gg*

    Schönen Abend!


Log in to reply