Speicher Freigeben, obwohl Program endet?



  • Hallo,

    Ist es nötig, dass ich den Speicher, den ich auf dem Heap angefragt habe freigebe, bevor ich mein Program mit return 0; beende?

    Da das Program sowieso gleich beendet wird, wird der Speicher doch automatisch freigegeben, oder?



  • Ja. Das solltest du grundsätzlich immer tun.

    (Es gibt Ausnahmen, aber die sind eher selten und wenn du so eine brauchst, dann weisst du das, ansonsten: Gib deinen Speicher immer frei!)

    Auch wenn das Betriebssystem dir den Speicher überlicherweise wieder frei gibt, ist das schlechter Stil, weil das nicht auf jedem System so sein muss (ist ja nicht vom Standard vorgeschrieben, dass angeforderter Speicher vom OS freigegeben werden muss, wenn das Programm endet).



  • Okay dankeschön!

    Kann ich das ganze auch so machen?

    class blabla {
      ~blabla() {
        delete this;
      }
    };
    


  • Sowas kann in gewissen Fällen nützlich sein, aber würde ich dir jetzt so nicht raten. Überleg dir mal was passiert, wenn du dein Objekt nicht per new anforderst, sondern automatisch anlegst? Also wenn du das hier machst:

    {
    blabla b;
    } //hups, jetzt crashts!
    


  • Samyboy schrieb:

    Kann ich das ganze auch so machen?

    class blabla {
      ~blabla() {
        delete this;
      }
    };
    

    Was bezweckst Du damit? Ich gehe mal davon aus, dass Du keine Endlosschleife haben willst, oder?



  • Naja, bei einem Fehler in meinem Program beende ich es mit:

    return 1

    und sonst halt ganz am Schluss von main() { mit return 0.

    Und anstatt ein delete blabla; 5-10 Mal zu schreiben, tu ich das ganze halt in den Destruktor :p



  • Nein, sorry. Das delete this ist an dieser Stelle völliger Unsinn.

    Überleg dir dazu was delete this macht.. Was ruft es auf? Genau den Destruktor des Objektes. Und was passiert in deinem Falle da? Genau es ruft wieder delete this auf. usw. das ist genau genommen keine Schleife, sondern ein Endloser rekursiver Aufruf. Eigentlich das hier:

    void foo ()
    {
     foo ();
    }
    

    Das endet mit einem Stack Overflow.

    delete this kann in Situationen innerhalb von z.B einer destroy Methode oder so Sinn machen, aber im Destruktor ist es völlig deplaziert.

    Wenn du kein delete schreiben möchtest, dann solltest du dir Smart Pointer anschauen.



  • Ahh jetzt versteh ich es erst 😃

    Danke!



  • Normalerweise sollte man sauber aufräumen und normalerweise geschieht das sowieso automatisch bei vernünftigem Einsatz von automatischen Objekten und Smartpointern.
    Zuweilen kann es aber sinnvoll zu sein, darauf zu achten, dass am Programmende möglichst wenig freigegeben wird. Ich hab hier z.B. einen Server, der Millionen kleine und größere Datenstrukturen im Speicher hat. Wenn das sauber am Ende wieder aufgeräumt wird, dauert es ewig. Für jedes Objekt wird da der Destruktor aufgerufen, der dann veranlasst, dass sich das Objekt aus irgendwelchen Listen austrägt usw. Dabei möchte man doch nur, dass sich der Server bitte schön nach dem Rausschreiben von ausstehenden Datenbankupdates u.ä. verabschiedet, damit man ihn neustarten kann. Da sollte man also darauf achten, dass man z.B. getInstance bei Singletons nicht etwa durch static Bla instance; implementiert, sondern Objekte mit new anlegt, damit sie am Programmende nicht automatisch zerstört werden.



  • Athar schrieb:

    Zuweilen kann es aber sinnvoll zu sein, darauf zu achten, dass am Programmende möglichst wenig freigegeben wird. Ich hab hier z.B. einen Server, der Millionen kleine und größere Datenstrukturen im Speicher hat. Wenn das sauber am Ende wieder aufgeräumt wird, dauert es ewig. Für jedes Objekt wird da der Destruktor aufgerufen, der dann veranlasst, dass sich das Objekt aus irgendwelchen Listen austrägt usw. Dabei möchte man doch nur, dass sich der Server bitte schön nach dem Rausschreiben von ausstehenden Datenbankupdates u.ä. verabschiedet, damit man ihn neustarten kann. Da sollte man also darauf achten, dass man z.B. getInstance bei Singletons nicht etwa durch static Bla instance; implementiert, sondern Objekte mit new anlegt, damit sie am Programmende nicht automatisch zerstört werden.

    Interessanter Ansatz. Wäre etwas, was ich einen kontrollierten Absturz nennen würde. 🙂



  • Geht auch einfacher mit exit() . 😉


Anmelden zum Antworten