Manuelle Speicherfreigaben bei Programmende
-
Hallo Allerseits!
Mir wurde beigebracht, bei Programmende dafür zu sorgen, dass jeder, vom Prozess reservierter Speicher, manuell wieder freigegeben werden muss.
Nur frage ich mich warum dies weiterhin so propagiert wird.
Denn jedes moderne Betriebssystem macht doch den Heap des Prozesses bei Beendigung sowieso 100%ig zu Nichte.
Warum also noch so einen Aufwand betreiben?Danke für eure Aufklärung!
-
Hi,
wenn sichergestellt ist, dass es sich wirklich um das Ende des Programms handelt, stimmt das schon ... allerdings weiß man meistens nur, dass die aktuelle Funktion oder der Lebenszyklus des aktuellen Objekts verlassen wird.
Und wenn das nutzende Programm eine Serveranwendung ist, die nur alle 6 Monate mal runtergefahren wird, passt das schon nicht mehr.Ich sage mal so: Nur in den allerseltensten Fällen werden Ressourcen im main() reserviert und dort freigegeben und nur da wäre das Weglassen von deletes halbwegs zuverlässig.
Ein ganz anderes Problem: Wer weiß, welche Ressourcen im Dtor noch so aufgeräumt werden ? Da könnten ganz schnell unangenehme Seiteneffekte auftreten. Fachliche wie ein DB-Rollback, weil im DTor ein Auto-Commit implementiert ist. Technische wie die Blockade einer Netzwerkressource, weil sie im System einen Timeout von 10 Minuten konfiguriert hat.....
Langer Rede kurzer Sinn: Einfach sauber bleiben ! Kostet nicht viel und spart viel Ärger.
Gruß,
Simon2.
-
Schon klar, dass wenn benötigt, z.B. die Auflösung eines Objekts aus funktionellen Gründen implementiert sein muß.
Mir geht es aber wirklich nur um die Frage ob es (heutzutage) irgend einen Grund geben könnte, Speicher explizit vor exit() freizugeben.
In dem (Win95-Era) Projekt woran ich gerade arbeite werden vor Programmende extra Listen usw. durchgegrast und deren Speicher freigegeben - und das wirklich nur der Speicherfreigabe wegen.Daher die Frage ob es irgend einen Sinn aus Sicht der Speicherverwaltung noch dafür gibt.
-
Aus ethisch-moralischen Gründen.
-
Räuber schrieb:
Daher die Frage ob es irgend einen Sinn aus Sicht der Speicherverwaltung noch dafür gibt.
Ist ohne Sinn!
-
Man räumt nunmal selbst auf, was man dreckig gemacht hat, Basta. Alles andere ist unsauber.
Ich schmeiße doch meine Kaugummipapiere auch nicht auf die Straße, obwohl ich genau weiß, dass die Stadtreinigung hier sowieso sauber macht. Gut, schlechter Vergleich.
-
Konrad Rudolph schrieb:
Ich schmeiße doch meine Kaugummipapiere auch nicht auf die Straße, obwohl ich genau weiß, dass die Stadtreinigung hier sowieso sauber macht. Gut, schlechter Vergleich.
Ja. Das OS tut ja nicht das, was du ohnehin machen würdest. Vor Programmende aufzuräumen ist ungefähr vergleichbar damit, nochmal das Treppenhaus zu fegen bevor die Abrißbirne einschlägt. OK, meine Tante würde das wahrscheinlich machen

-
Bashar schrieb:
Vor Programmende aufzuräumen ist ungefähr vergleichbar damit, nochmal das Treppenhaus zu fegen bevor die Abrißbirne einschlägt.
den muss ich mir merken

-
Bashar schrieb:
Konrad Rudolph schrieb:
Ich schmeiße doch meine Kaugummipapiere auch nicht auf die Straße, obwohl ich genau weiß, dass die Stadtreinigung hier sowieso sauber macht. Gut, schlechter Vergleich.
Ja. Das OS tut ja nicht das, was du ohnehin machen würdest. Vor Programmende aufzuräumen ist ungefähr vergleichbar damit, nochmal das Treppenhaus zu fegen bevor die Abrißbirne einschlägt. OK, meine Tante würde das wahrscheinlich machen

Da würde ich dann aber auch zum stylishen Programmende mittels
throw;raten.

*SCNR*
Grüsse
*this
-
Gast++ schrieb:
Da würde ich dann aber auch zum stylishen Programmende mittels
throw;raten.

wie wärs mit:
exit(0);oder, noch lustiger:
asm hlt;
-
pale dog schrieb:
Gast++ schrieb:
Da würde ich dann aber auch zum stylishen Programmende mittels
throw;raten.

wie wärs mit:
exit(0);oder, noch lustiger:
asm hlt;
Was sind denn das für Stilblüten? 
SO macht man das:__asm { mov cr0,42 } // This is how REAL programmers do it!
Grüsse
*this
-
Gast++ schrieb:
SO macht man das:
DAS ist aber nicht portabel :p
-
Räuber schrieb:
Schon klar, dass wenn benötigt, z.B. die Auflösung eines Objekts aus funktionellen Gründen implementiert sein muß....
Das bedeutet also, dass Du Dir genau die Implementierung aller direkt und indirekt genutzten Klassen ansehen möchtest, in der Hoffnung, festzustellen, ob sie "funktionelle Auflösungsgründe" haben ... und Dir dann ein paar deletes zu sparen ?
Wäre mir irgendwie zu lästig und ich sehe da wenig Vorteil drin (mal ganz davon abgesehen, dass das in der nächsten Version dieser Objekt schon anders sein kann).Denk dran: Ohne delete kein Dtor von Heapobjekten und ohne return oder gefangene Exception kein Dtor von Stackobjekten .... irgendwie sehe ich nicht, wo das als Standardverhalten gewinnbringend wäre. Das "Scopeverhalten" hilft mir in der Designphse, mir gründlich Gedanken über Ownership und Abhängigkeiten zu machen - Gedanken, die sich im Gesamtdesign bezahlt machen (nicht nur durch Aufruf der Dtoren).
Gruß,
Simon2.
-
pale dog schrieb:
Gast++ schrieb:
SO macht man das:
DAS ist aber nicht portabel :p
LOL

Einen Bolzen hab ich noch:
So konnte man früher mit dem gcc mal ekegant (und portabel) die Tür schliessen:class A { public: virtual void foo() = 0; A() {foo();}; }; class B : public A { public: virtual void foo() {}; B() {}; }; B b;Ja, da guckst Du: "Pure virtual function call" - so ne Exception kriegt nicht jeder hin!

Hab hier grad keinen gcc zum Testen
- [EDIT] Müll [/EDIT]Grüsse
*this
-
Das dürfte beim gcc immernoch so sein, generell ist das Verhalten undefiniert, muss also (z.B. beim MSVC) nicht abstürzen

EDIT: Der MSVC gibt sogar nen Linkerfehler, weil er im Ctor von A garnicht versucht über die vtable zu gehen. Also sucht er nach A::foo(), welches es nicht gibt. Schlauer Compiler

-
Bashar schrieb:
Vor Programmende aufzuräumen ist ungefähr vergleichbar damit, nochmal das Treppenhaus zu fegen bevor die Abrißbirne einschlägt. OK, meine Tante würde das wahrscheinlich machen

Deine Tante ist mir sympathisch.

Ne im Ernst: Das würde ja bedeuten, dass man eine Sonderbehandlung für solche Variablen einführen müsste, die bis zum Programmende existieren. Denn bei allen anderen Variablen muss man sich ja auch darum kümmern, dass sie ordnungsgemäß entsorgt werden. Und andere unverwaltete Ressourcen, also z.B. Grafik-Handles etc. müsste man auch weiterhin selbst freigeben, weil dies das Betriebssystem eben nicht unbedingt übernimmt.
=> Diese Sonderbehandlung für ganz gewisse Variablen ist auf jeden Fall sehr viel mehr Aufwand, und damit potentiell fehleranfälliger, als einfach jede Ressource ordnungsgemäß zu entsorgen.
-
Konrad Rudolph schrieb:
Und andere unverwaltete Ressourcen, also z.B. Grafik-Handles etc. müsste man auch weiterhin selbst freigeben, weil dies das Betriebssystem eben nicht unbedingt übernimmt.
doch, macht es.
das OS meldet sogar netzwerkverbindungen bei der gegenstelle ab, wenn dein programm abraucht.
kritisch wird's vielleicht bei nichtflüchtigen sachen wie temporäre dateien und registry-einträge o.ä. die bleiben natürlich erhalten.

-
Der Speicher sollte auf jeden Fall freigegeben werden. Es gibt noch andere Plattformen als BSD, Linux und Windows auf x86ern oder ähnlichem.
Nehmen wir z.B. DSP's. Da gibt es (meistens) kein OS, welches irgendwas hinter einem her räumt. Wohl aber Frameworks, die Prozesse in definierter Reihenfolge abarbeiten. Wenn so ein Prozess, aus welchen Gründen auch immer, terminiert, muss der Speicher freigegeben werden. Gibt noch andere (bessere) Beispiele, auf jeden Fall sollte man sich da nicht auf das OS verlassen.
-
pale dog schrieb:
Konrad Rudolph schrieb:
Und andere unverwaltete Ressourcen, also z.B. Grafik-Handles etc. müsste man auch weiterhin selbst freigeben, weil dies das Betriebssystem eben nicht unbedingt übernimmt.
doch, macht es.
Ich weiß nicht, ob es ein Bug oder by design ist, aber Windows gibt definitiv nicht immer alle GDI-Handles frei. Ich weiß nicht, auf welche Versionen das zutrifft aber das Verhalten ließ sich recht einfach reproduzieren. Hier musste man wirklich manuell nacharbeiten.
-
Tachyon schrieb:
Der Speicher sollte auf jeden Fall freigegeben werden. Es gibt noch andere Plattformen als BSD, Linux und Windows auf x86ern oder ähnlichem.
Nehmen wir z.B. DSP's. Da gibt es (meistens) kein OS, welches irgendwas hinter einem her räumt. Wohl aber Frameworks, die Prozesse in definierter Reihenfolge abarbeiten. Wenn so ein Prozess, aus welchen Gründen auch immer, terminiert, muss der Speicher freigegeben werden.diese prozesse laufen aber nicht in einer sandbox wie z.b. windows user-mode prozesse. wenn da einer mist baut, dann leidet das ganze system darunter. es reicht ja schon, wenn eine globalen speicherverwaltung benutzt wird und ein prozess regelmässig free oder delete auslässt.
Tachyon schrieb:
Gibt noch andere (bessere) Beispiele, auf jeden Fall sollte man sich da nicht auf das OS verlassen.
ja, die alten windosen wie windoofs 3.11, 95, 98, me.
die waren sowas von schlecht...

Konrad Rudolph schrieb:
Ich weiß nicht, ob es ein Bug oder by design ist, aber Windows gibt definitiv nicht immer alle GDI-Handles frei.
das war bei den alten 16-bittigen wins der fall (siehe oben)