Soll ich vor dem Beenden Speicher freigeben?

Lesezeit: 7 Minuten

Benutzeravatar von Lucafia
Lucafia

Sollte ich meinen gesamten nicht zugewiesenen Speicher freigeben, wenn ich das Programm aufgrund eines Fehlers beende?

something = (char**) malloc (x * sizeof(char*));
for (i = 0; i < x; i++)
    something[i] = (char*) malloc (y + 1);

...

if (anything == NULL) {
   printf("Your input is wrong!");
   // should I free memory of every mallocated entity now?
   exit(1);
} 
else {
   // work with mallocated entities
   ...
   free(something); // it must be here
   system("pause);
}

  • Ich sehe keinen Grund. OS erledigt das für Sie.

    – Aleksandar Makragić

    12. April 2016 um 21:09 Uhr

  • Aber es ist eine gute Angewohnheit, nach sich selbst zu putzen.

    – Eugen Sch.

    12. April 2016 um 21:10 Uhr

  • Es stimmt zwar, dass das Betriebssystem dies für Sie erledigt, aber was passiert, wenn OP eine neue Funktion hinzufügt, um einige Verarbeitungsschritte durchzuführen, und dann noch eine und dann noch eine? Oder noch schlimmer, wenn der neue Typ (Mädel) kommt und anfängt zu modifizieren? Mein Rat, geben Sie den gesamten zugewiesenen Speicher frei. Oh, und werfen Sie nicht die Ergebnisse Ihrer Zuordnungen. Je.

    – KevinDTimm

    12. April 2016 um 21:11 Uhr


  • Mögliches Duplikat von Wird Speicherlecks freigegeben, wenn das Programm beendet wird?

    – Adrian McCarthy

    12. April 2016 um 21:34 Uhr

  • Ein Vorteil des Nicht-Freigebens besteht darin, dass, wenn Ihr Programm eine große Anzahl von Zuordnungen hat, das Freigeben beim Beenden die Beendigungssequenz Ihrer Anwendung verlangsamt.

    – MM

    12. April 2016 um 21:53 Uhr

Benutzeravatar von Steve Summit
Steve Gipfel

Das ist eigentlich eine wirklich schwierige, unwägbare Frage.

Pro (dafür, alles vor dem Beenden freizugeben):

  • keine Fehler oder Speicherlecks später, wenn der Code neu angeordnet wird
  • keine Fehlalarme von Valgrind oder Memory Leak Checker
  • keine Speicherlecks, wenn Sie unter einem fehlerhaften Betriebssystem oder gar keinem Betriebssystem laufen

Con (einfach beenden, keine Sorge, alles zu befreien):

  • Alles zu befreien kann eine Menge Arbeit sein
  • Alles zu befreien kann Fehler und Abstürze verursachen
  • Ihr Betriebssystem sollte wirklich, wirklich alle Ressourcen für Sie zurückfordern, wenn Sie es beenden

Und noch ein Punkt (nicht sicher, ob es ein Pro oder ein Contra ist): auf den meisten Systemen anrufen free tut nicht Speicher an das Betriebssystem zurückgeben (nur das Beenden tut das).

Am Ende müssen Sie entscheiden, welches dieser Vor- und Nachteile für Sie am wichtigsten ist. Unterschiedliche Programmierer an unterschiedlichen Projekten unter unterschiedlichen Umständen werden zu unterschiedlichen Schlussfolgerungen kommen; hier gibt es keine pauschale antwort.

Siehe auch diese vorherige Stack Overflow-Frage. Siehe auch Frage 7.24 in dem C FAQ-Liste.

  • Gut gesagt! Um einen Kommentar zu wiederholen, den ich unten gemacht habe: Wenn Sie ein Neuling sind, machen Sie im Allgemeinen “manuell befreien” zum gewohnheitsmäßigen Instinkt (weniger gefährliche Gewohnheit) und machen Sie “es dem Betriebssystem überlassen” zu einem bewussten, informierten Fall – Fallentscheidung. Der Entscheidungsprozess dafür wird mit der Zeit zum Instinkt. Andernfalls vergessen Sie gewöhnlich, Ihre Mallocs freizugeben und Ihre baumelnden Zeiger zu bereinigen, und Sie melden sich anschließend für Überraschungs-UBs an, wenn Sie Ihren Code das nächste Mal so ändern, dass der Speicher jetzt nicht freigegeben wird Angelegenheiten.

    – CodeMouse92

    12. April 2016 um 21:40 Uhr


  • @JasonMc92 Das klingt zwar nett, baut aber zusätzliche Unzuverlässigkeit in den heutigen Code ein. Das explizite Freigeben von Speicher beim Beenden der App ist nicht kostenlos, nicht sicher und nicht immer möglich. Es handelt sich normalerweise um unnötigen zusätzlichen Code, der auf allen Betriebssystemversionen immer und immer wieder getestet und debuggt werden muss. Es sind Uni-Cargo-Kult-Mantras wie „Sie müssen immer explizit freigeben, bevor Sie beenden“, die dazu führen, dass die vielen Apps, die wir beide verwendet haben, nicht sauber und schnell heruntergefahren werden: (

    – Martin Jakob

    13. April 2016 um 12:00 Uhr


  • Wie ich in der anderen (längeren) Kommentarkette sagte: Der Link in der Antwort bestätigt meinen Standpunkt. Im Großen und Ganzen manuell befreien (insgesamt, nicht nur am Programmende) ist dabei meist eine Frage der Stabilität (kurz- und langfristig). nicht manuell befreien ist normalerweise eine Frage der Leistung, und wir alle kennen das Sprichwort: „Vorzeitige Optimierung ist die Wurzel allen Übels.“ (-Donald Knuth). Frei aus Gewohnheit, entscheide dich dafür, es nicht zu tun, nicht um sicherzustellen, dass das Betriebssystem den Speicher zurückerhält, sondern um Fehler zu vermeiden, wenn wir den Code später umgestalten. Darüber hinaus haben wir einen “Heiligen Krieg” und sollten uns wohl am besten einigen, anderer Meinung zu sein.

    – CodeMouse92

    13. April 2016 um 14:50 Uhr


  • Ich fand, dass das Ausführen unter keinem Betriebssystem das ultimative ohne Speicherlecks ist. Wenn Ihr Exit das nächste Programm in einer Kette lädt, erscheint es genau wie Ihres und sieht den gesamten Speicher im Computer als zufällig initialisierten freien Speicher.

    – Josua

    16. August 2018 um 22:06 Uhr

  • Sie könnten argumentieren, dass das Programm schlecht konzipiert ist, wenn es viel Arbeit kostet, es zu befreien.

    – klutt

    4. August 2020 um 7:52 Uhr

Sie sollten vor dem Beenden immer zugewiesenen Speicher freigeben. Wie bereits in anderen Antworten erwähnt, werden dadurch Warnungen von statischen oder dynamischen Analysetools usw. minimiert.

Aber der wahre Grund, warum Sie dies immer tun sollten, ist, dass das Freigeben oft schlafende Laufzeitfehler in Ihrer Anwendung aufdeckt.

Wenn Sie irgendwo einen Fehler haben, der Speicherbeschädigungen verursacht oder Zeigeradressen ändert, kann dieser Fehler still und inaktiv bleiben. Bis Sie etwas völlig anderes als den Fehler ändern und dadurch das Speicherlayout mischen. Dann kommt es plötzlich zu einem Absturz und Sie haben keine Ahnung warum, denn der Fehler befindet sich nicht einmal in dem Code, den Sie gerade hinzugefügt haben.

Indem Sie den Speicher freigeben, provozieren Sie das Auftauchen solcher Fehler. Denn wenn etwas mit dem Heap oder mit den Zeigern, die auf den Heap zeigen, nicht in Ordnung ist, kommt es häufig zu einem Absturz an der Stelle, an der Sie aufrufen free(). Das bedeutet, dass Sie irgendwo einen schwerwiegenden Fehler haben, den Sie finden müssen, bevor Sie das Programm ausliefern.

  • Diese Antwort ist gut, weil sie über die Idee hinausgeht, nur den Teil des Themas “Heiliger Krieg” zu diskutieren. Danke @Lundin, wertvolle Punkte!

    – Per Lundberg

    16. Dezember 2017 um 14:10 Uhr

Harrys Benutzeravatar
Harry

Es hängt vom Betriebssystem ab. Best Practice Ich würde sagen, Sie sollten es explizit freigeben. Es macht auch die Verwendung von Tools wie Valgrind zu einem PITA, wenn Sie nicht überall Speicher freigegeben haben und ich nicht sagen kann, was gut und schlecht ist usw.

Wenn Sie auf einem Betriebssystem explizit Speicher freigeben, haben Sie immer noch das Problem anderer Ressourcen. Wenn Ihre App zu wachsen beginnt und Bibliotheken von Drittanbietern hinzuzieht, kann es zu Ressourcenlecks kommen. Stellen Sie sich vor, ich habe eine Bibliothek geschrieben, die Sie auffordert, einen Handler zu schließen. Dieser Handler wird zufällig von temporären Dateien unterstützt, die nicht gelöscht werden, es sei denn, Sie rufen close auf. Oder ich habe getrennte Prozesse, die im Hintergrund ausgeführt werden und die ich mithilfe von Signalen oder einer anderen Ressource verwalte, die Sie nicht kennen.

  • Welche Systeme können nach Programmende keinen Speicher freigeben?

    – fuz

    12. April 2016 um 21:22 Uhr

  • Werfen Sie einen Blick in die Kommentare hier … stackoverflow.com/questions/2975831/… und hier. stackoverflow.com/questions/6727383/…

    – Harry

    12. April 2016 um 21:26 Uhr


  • Der Umgang mit temporären Dateien besteht darin, sie beim Hochfahren zu löschen, nicht beim Herunterfahren. Die Stromversorgung kann jederzeit ausfallen, und Apps, die unbedingt auf ein Herunterfahren angewiesen sind, geraten in Schwierigkeiten.

    – Martin Jakob

    12. April 2016 um 21:28 Uhr


  • @Harry Wenn Sie für ein solches System programmieren, wissen Sie das und stellen diese Art von Frage nicht bei Stack Overflow.

    – fuz

    12. April 2016 um 21:30 Uhr

  • @MartinJames beides? Lass kein Chaos zurück, Boykott-Prinzip und alles

    – Schlitten

    30. Januar 2019 um 22:38 Uhr

Sie müssen vor dem Beenden des Programms keinen Speicher freigeben. Das Beenden des Programms in irgendeiner Weise bewirkt, dass der gesamte Speicher automatisch freigegeben wird.

Benutzeravatar von Yuriy Vasylenko
Juri Wasylenko

Ich hatte ein völlig entgegengesetztes Szenario: Segfaulting-Destruktoren von statischen Objekten aus der Bibliothek eines Drittanbieters. Nur wegen der expliziten Freigabe von Speicherpools vor dem Beenden. Ich glaube, es ist besser, vernünftig zu sein und sich auf die Programmstruktur zu konzentrieren.

1397630cookie-checkSoll ich vor dem Beenden Speicher freigeben?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy