Aliobaba hat geschrieben: Do 27. Jan 2022, 14:02
1. Was passiert eigentlich, wenn man am Ende einer Prozedur ein (z.B.) StringList nicht frei gibt?
2. Ich glaube, ich habe verstanden, dass dann wohl kleine Adressbereiche im Speicher ungenutzt als "garbage" besetzt bleiben?
Bei einer StringList handelt es sich ja um eine Klasseninstanz, die Variable ist nur eine Referenz auf den Speicherblock, wo die eigentliche Instanz liegt (Also ein Pointer aber in anderer Gestalt). Deshalb kann man Klasseninstanzen zuweisen und kopiert die Daten dabei nicht.
Wenn jetzt die Variable selbst, also die Referenz, nicht mehr vorhanden ist, weil sie nur lokal war und nicht auf irgend eine Art übergeben wurde, ist der Speicherblock nach wie vor vorhanden, das Programm hat aber keinen Zugriff mehr. -> Speicherleck
3. Ist das bei den heutigen Speichergrößen noch ein reelles Problem?
Das wird dann zum handfesten Problem, wenn die Funktion oft aufgerufen wird und das Programm längere Zeit läuft.
4. oder eher eine "kosmetisch bedingte" Übereinkunft im Kapitel "Schöner programmieren"?
Für einmalig gebrauchten Speicher, der ja dann im "Verbrauch" überschaubar ist, trifft das zu. Allerdings, um echte kritische Speicherlecks zu erkennen gibt es den HeapTrace. Der beim Beenden vom Programm alle nicht freigegebenen Variablen auflistet. Hat man da zig Blöcke drin, bei denen man sagt das bisschen Speicher macht ja nichts, dann ist der HeapTrace kaum zu gebrauchen. Also ja, ein sauberes Programm räumt den Speicher komplett auf.
Bei einem Quick-und-Dirty-Progrämmchen seh ich es nicht so kritisch, beim Beenden vom Programm räumt das Betriebssystem letztlich auf.
5. Ich vermute, dass, wenn eine StringListe, die innerhalb einer Funktion/Prozedurdeklariert worden ist, nicht frei gegeben wird, diese in einer anderen Prozedur/Funktion auch dann einen neuen Speicherbereich beansprucht, wenn diese den selben Namen hat.
Ja. Und wenn die Funktion öfters aufgerufen wird, wird eben jedes Mal von Neuem Speicher reserviert.
6. Müsste man dann konsequenterweise nicht auch jeden "String" oder jeden "Integer"-Wert, der in Prozeduren oder Funktionen deklariert wird, auch frei geben?
Globale Variablen existieren die ganze Zeit, solange das Programm läuft, der Compiler kümmert sich darum (Statischer Speicher). Lokale Variablen liegen auf dem Stack und existieren nur solange die Funktion durchlaufen wird. Der Compiler fügt am Anfang der Funktion Code ein, der den Speicher für die Variablen auf dem Stack reserviert (Stack Frame) und fügt am Ende der Funktion Code ein, der den Speicher wieder frei gibt. Solche normale Variablen "leben" also nur entweder über die ganze Programmlaufzeit oder über die Laufzeit einer Funktion/Prozedur.
Klasseninstanzen werden im dynamischen Speicher abgelegt. Und zwar wird er beim Aufruf des Konstruktors reserviert. Die Variable selbst, also die Referenz auf den Speicherblock hat die Lebenszeit wie eine 'normale' Variable.