Variablen wieder löschen/freigeben?



  • Hallo,

    ich bin gerade dabei, Funktionen für doppelt verkettete Listen zu implementieren und dabei sind mir Fragen aufgekommen. Und zwar wollte ich eine Funktion schreiben, die einen Pointer auf die Liste, einen Pointer auf das vorherige Element (für die Position) und einen double-Wert für den Wert des Listenelements bekommt und dann ein eben solches Listenelement einfügt.

    Jetzt hatte ich das so gemacht, dass ich in dieser Funktion ein solches struct als static deklariert habe und dann halt davon die Adresse zurückgegeben habe. Nur hatte ich dann ein Problem, als ich ein Listenelement wieder löschen wollte. Zwar kann man das Element durch Umstellen der Pointer sozusagen aus der Liste rausnehmen, aber der belegte Speicher bleibt ja bei dieser Methode, wodurch sich mir folgende Frage stellte:

    Kann ich eine Variable wieder freigeben, um Speicherplatz zu sparen?

    Werde es jetzt auf jeden Fall mit malloc machen, dann sollte das Freigeben ja kein Problem sein, aber eine Antwort auf obige Frage wüsste ich trotzdem gerne.

    Edit:
    Und noch was, nur zum Verständnis;
    Angenommen, ich deklariere einen struct *a. Wird dann praktisch doppelt Speicherplatz benutzt? Zum Einen wird irgendwo diese struct reingeschrieben und zum Anderen irgendwo ein Int-Wert, der die Adresse von dieser struct repräsentiert, oder?

    MfG plizzz



  • plizzz schrieb:

    Jetzt hatte ich das so gemacht, dass ich in dieser Funktion ein solches struct als static deklariert habe und dann halt davon die Adresse zurückgegeben habe.

    das ist nicht gut. wenn das objekt in der funktion 'static' ist, dann wird immer dasselbe objekt zurückgegeben (falls du's als pointer zurückgibts). es wird also kein neues objekt erzeugt.

    plizzz schrieb:

    Nur hatte ich dann ein Problem, als ich ein Listenelement wieder löschen wollte. Zwar kann man das Element durch Umstellen der Pointer sozusagen aus der Liste rausnehmen

    ja, so funzt das.

    plizzz schrieb:

    ...aber der belegte Speicher bleibt ja bei dieser Methode, wodurch sich mir folgende Frage stellte:
    Kann ich eine Variable wieder freigeben, um Speicherplatz zu sparen?
    Werde es jetzt auf jeden Fall mit malloc machen, dann sollte das Freigeben ja kein Problem sein

    ja, zuerst die pointer umhängen (vorher einen pointer auf das zu löschende objekt sichern) und dann das objekt mit 'free()' killen.

    plizzz schrieb:

    Und noch was, nur zum Verständnis;
    Angenommen, ich deklariere einen struct *a. Wird dann praktisch doppelt Speicherplatz benutzt? Zum Einen wird irgendwo diese struct reingeschrieben und zum Anderen irgendwo ein Int-Wert, der die Adresse von dieser struct repräsentiert, oder?

    nö, ein struct* belegt nur den speicherplatz eines struct* (wie mit allem anderen auch, int, void*, char, usw).
    🙂



  • Ok, soweit so gut.
    Aber nun angenommen, ich definiere einen struct *a. Wenn ich jetzt malloc(sizeof(struct)) benutze, wird ja Speicher alloziiert, der erstmal nur die Größe hat, die so ein struct hat. Wenn ich jetzt allerdings sowas mache wie
    a=malloc(sizeof(struct)), dann sollte dort ja auch eine entsprechende struct erstellt werden, oder?

    Weitere Frage: Wenn ich einfach nur malloc benutze, ohne dass ich malloc einer Variable zuweise, sprich einfach malloc(...) irgendwo im Code - wird dann überhaupt Speicher reserviert? Und wenn ja, wie gibt man diesen wieder frei? Oder ist das einfach mies programmiert, man sollte es nicht tun und kann es erstmal gar nicht wieder selbst freigeben?



  • plizzz schrieb:

    Ok, soweit so gut.
    Aber nun angenommen, ich definiere einen struct *a. Wenn ich jetzt malloc(sizeof(struct)) benutze, wird ja Speicher alloziiert, der erstmal nur die Größe hat, die so ein struct hat. Wenn ich jetzt allerdings sowas mache wie
    a=malloc(sizeof(struct)), dann sollte dort ja auch eine entsprechende struct erstellt werden, oder?

    in beiden fällen wird speicher für eine struct geholt. bei 'a=malloc(sizeof(struct))' wird zusätzlich noch die anfangsadresse der neuen struct in a gespeichert. so muss das auch sein.

    plizzz schrieb:

    Weitere Frage: Wenn ich einfach nur malloc benutze, ohne dass ich malloc einer Variable zuweise, sprich einfach malloc(...) irgendwo im Code - wird dann überhaupt Speicher reserviert?

    ja, aber sowas ist ziemlich sinnlos, weil du dann nicht auf den speicher zugreifen kannst, wenn der rückgabewert von 'malloc' ignoriert wird.

    plizzz schrieb:

    Und wenn ja, wie gibt man diesen wieder frei?

    das geht auch nicht. der rückgabewert (pointer auf das neu angelegte objekt) muss irgendwo gespeichert werden.
    🙂



  • Achso, ich hatte unterbewusst irgendwie so die Vorstellung, dass der Compiler sich irgendwie so eine Art struct im Speicher anlegen muss. Wie funktioniert denn ein Zugriff auf eine struct?

    Ist das wie Pointerarithmetik bei einem Array zu verstehen? Sprich, ich habe eine struct und die hat eine Adresse und wenn ich nun struct.data3 aufrufe, dann greife ich auf den Speicherplatz &struct+sizeof(data1)+sizeof(data2) zu? Oder wie läuft das?



  • plizzz schrieb:

    Ist das wie Pointerarithmetik bei einem Array zu verstehen? Sprich, ich habe eine struct und die hat eine Adresse und wenn ich nun struct.data3 aufrufe, dann greife ich auf den Speicherplatz &struct+sizeof(data1)+sizeof(data2) zu? Oder wie läuft das?

    Ja, vom Prinzip her wird es genau so gemacht.



  • plizzz schrieb:

    Ist das wie Pointerarithmetik bei einem Array zu verstehen? Sprich, ich habe eine struct und die hat eine Adresse und wenn ich nun struct.data3 aufrufe, dann greife ich auf den Speicherplatz &struct+sizeof(data1)+sizeof(data2) zu? Oder wie läuft das?

    kommt drauf an. wenn der compiler indirekte zugriffe schon selber auflösen kann, dann ist es wie ein zugriff auf 'ne normale variable. wenn nicht, dann rechnet das programm zur laufzeit etwa: effektive_adresse = struct_basis_adresse+offset_zum_member.
    🙂



  • Ist das wie Pointerarithmetik bei einem Array zu verstehen? Sprich, ich habe eine struct und die hat eine Adresse und wenn ich nun struct.data3 aufrufe, dann greife ich auf den Speicherplatz &struct+sizeof(data1)+sizeof(data2) zu? Oder wie läuft das?

    Weil das aber nur vom Prinzip her so gemacht wird, gibt es den Operator ->. Den kennst du schon, oder?



  • Ja, den kenne ich.
    Es ging mir darum, dass ich in einem Code gesehen habe, dass jemand einen Pointer auf eine struct definiert hat, dann mit malloc Speicher zugewiesen hat und von nun an auf diese struct zugreifen konnte (mit ->). Deshalb habe ich mich gefragt, wie das eigentlich geht, da an sich ja nicht so eine struct erstellt wurde, sondern nur ein Häufchen Speicher mit einem Pointer dazu.



  • Deshalb habe ich mich gefragt, wie das eigentlich geht, da an sich ja nicht so eine struct erstellt wurde, sondern nur ein Häufchen Speicher mit einem Pointer dazu.

    Das macht in C keinen eigentlichen Unterschied, wie aus dem Thread hervorgeht. Mit den Operatoren . und -> sagt man dem Compiler nur, dass er sich darum zu kümmern hat, wie die Komonenten abgelegt werden.

    Sprich, ich habe eine struct und die hat eine Adresse und wenn ich nun struct.data3 aufrufe, dann greife ich auf den Speicherplatz &struct+sizeof(data1)+sizeof(data2) zu?

    Kannst du ja einmal versuchen! Geht in den meisten Fällen gut, nur in manchen Fällen stösst man auf Füllbytes.



  • Ist dies hier zulässiger Code, um eine Liste mitsamt seinen Elementen freizugeben? Ich weiß, dass ich das Problem locker mit nem Pointer *tmp umgehen könnte, aber es interessiert mich vom Prinzip her.

    void list_free(LISTHEAD* list){
    
    	LISTELEMENT* aktuell;
    
    	aktuell = list->first;
    
    	while(aktuell != NULL){
    		free(aktuell);
    		aktuell = aktuell->next;
    	}
    
    	free(list);
    }
    

    Ich benutze ja free für aktuell, mache dann ja allerdings nichts mehr, wodurch ich aktuell überschreiben könnte, also müsste ja ein Zugriff auf aktuell->next möglich sein, oder nicht?

    Es könnte aber wohl noch passieren, dass andere Prozesse sich den Speicher schnappen und es dadurch zu Fehlern kommt, oder?



  • Es könnte aber wohl noch passieren, dass andere Prozesse sich den Speicher schnappen und es dadurch zu Fehlern kommt, oder?

    Ja. Oder dass das Programm abschmiert, weil das Betriebsystem das Lesen nicht zulässt. Oder dass dir Dämonen aus der Nase fliegen. Aber jedenfalls spannend.


Log in to reply