Richtig/sauber freigeben - nur wie?
Hallo DP!
Fast ist es mir peinlich, so eine Frage zu stellen, aber ich glaube, ich hab das nie richtig gelernt/kapiert: Ich habe (beispielsweise) folgende Struktur:
Delphi-Quellcode:
Und würde natürlich gerne auch sauber freigeben, was ich an Speicher verbrate.TFontSpec=record vFontID:integer; vFamily:TFontFamily; vName:string; end; TFontTable=class private vContent:array of TFontSpec; {...} public constructor Create; {...} destructor Destroy; override; end; Bis jetzt habe ich im Destruktor allerdings nur
Delphi-Quellcode:
stehen. Meines Wissens nach gibt das den Speicher aber noch nicht wieder frei:cry:
SetLength(vContent, 0);
Und wie man (hier) mit FreeMem/Finalize/Initialize/New/etc. ist mir leider noch ein Rätsel; ich weiß auch nicht, wo(bestimmt gibts was hier :D) ich wie(?????) anfange sollte zu suchen :( Wäre euch sehr dankbar, wenn ihr mich an ein andres Thema verweisen könntet, wo was dazu steht (oder schnell selbst ne verständliche Erklärung hintippt :)) Danke schonmal im Voraus, Euer LDer. |
Re: Richtig/sauber freigeben - nur wie?
Hallo
Meine Grundregel lautet, nur was ich mit .create anlege muss ich mit .free auch wieder freigeben. ==> Da ich den Record nicht .create anlege muss ich mich nicht um die freigabe kümmern. ( Ich hoffe ich habe Recht) mfg Reinhold ------------ www.ithof.de Arzneimittelbuch für Tierhalter |
Re: Richtig/sauber freigeben - nur wie?
Zitat:
Aber davon mal abgesehen, das SetLength auf 0 sollte den Speicher defakto auch wieder freigeben. Ausser natürlich, TFontFamily ist ein Objekt oder ein Struct, welches Objekte enthält. Das bedeutet, du müsstest dann vorher im Destruktor deiner Table durch fontSpecifications durchlaufen und alle Objekte in dem Array manuell freigeben. Betrifft wie gesagt nur Objekte - Structs und Wertetypen sind aussen vor, die werden sofort sauber freigegeben. |
Re: Richtig/sauber freigeben - nur wie?
Zitat:
Im Destroy werden dann auch die angehängten Objekte vernichtet (OwnsObjects = True). Man kann sich hier also entscheiden. Letztendlich hängt es vom Code ab, ob die angehängten Objekte aus dem Speicher entfernt werden sollen oder nicht. |
Re: Richtig/sauber freigeben - nur wie?
Wie rweinzierl schon sagt, muß man vorallem erstmal alles selber freigeben, welches mal per .Create (oder Funktionen, wo das drinsteckt), New, GetMem und Co. selber angelegt hat und wo soich natürlich kein Anderer um die Freigabe kümmert.
Ausnahmen sind Objekte in ObjektListen, welche die enthaltenen Objekte selber freigeben, wenn man die Objektliste freigibt. Strings, dynamische Arrays und Interfaces werden von Delphi freigegeben. > Ausnahmen sind wiederum z.B. Sachen in Records innerhalb eines Arrays, welche man selber angelegt hat also Fazit: dein Array und die Strings darin würden im Destructur von Delphi automatisch freigegeben, aber es kann nicht schaden, wenn du es selber freigibst. Im Endefekt kannst du auch mal FastMM einbauen und dessen Speicherüberwachung aktivieren oder ein anderes Kontrollprogramm installieren, welches prüft, ob du alles freigegeben hast. |
Re: Richtig/sauber freigeben - nur wie?
Alles klar, klingt gut, dann hab ich ja doch nich so viel falsch gemacht, wie ich dachte :)
Übrigens, mein TFontFamily ist ein ENUM ;) also müsste's ja auch freigegeben werden :D Bis dann, Gruß, LDer. |
Re: Richtig/sauber freigeben - nur wie?
Eine weitere Ausnahme: Komponenten. Der im Konstruktor übergebne Owner kümmert sich bei seiner Freigabe um die ihm zugeteilten Komponenten.
|
Re: Richtig/sauber freigeben - nur wie?
Zitat:
|
Re: Richtig/sauber freigeben - nur wie?
Die Regeln die ihr hier aufgeschrieben habt, kannte ich soweit schon, nur war ich nicht sicher, ob Standardtypen wie strings, integer, enums, booleans(...) atomatisch bereinigt werden ;)
Trotzdem danke für eure Mühe! Grüße natürlich noch :D, Der LDer. |
Re: Richtig/sauber freigeben - nur wie?
Integer, Enums und Booleans reservieren ja keinen eigenen/eigenständigen Speicher, liegen direkt im Record und werden somit samt dem zugehörigen Record entsorgt.
Strings (abgesehn vom ShortString), dynamische Arrays, Objekte und Interfaces sind dagegen im Record "nur" Zeiger auf die entsprechenden Daten. |
Re: Richtig/sauber freigeben - nur wie?
Zitat:
|
Re: Richtig/sauber freigeben - nur wie?
Zitat:
Nix, außer dass du dich bei Variablen, welche nicht Objekte oder Pointer sind, auch niemals um die Freigabe kümmern musst. Da dies für dein Record zutrifft, brauchst du auch nichts löschen. Das wird automatisch erledigt. |
Re: Richtig/sauber freigeben - nur wie?
Zitat:
Daß es nun darauf ankommt, ob es für diese Daten eine entsprechende Automatik gibt. Strings und dynamische Arrays werden von der CompilerMagic behandelt. bei Interfaces ist es ähnlich Auch wenn du Records via New/Dispose erstellst/löschst oder selber Speicher z.B. via GetMem/FreeMem/Initialize/Finalize verwaltets greift die CompilerMagic ein. Diese CompilerMagic behandelt auch alle Variablen, welche in Funktions-Parametern, als lokale/globale Variablen, in Arrays oder als Class-/Instanzvariablen in Objekten drin stecken Dann gibt es eben noch Objekte, welche beim Dispose/Free eine in ihnen angelegte Liste selber bereinigen. So, nun Interger, Sets, Enums, Chars ... liegen halt direkt im Record und da sie keinen eigenen Speicher besitzen werden sie praktisch mit dem Record entfernt/erstellt. Alles was jetzt außerhalb des Records liegt und im Record nur einen Zeiger hat muß nun irgendwie extra behandelt (gelöscht) werden. Da nun das Array ja von der CompilerMagic freigegeben wird, kümmert sich diese auch im die enthaltenen Records und gibt auch dort "alles" frei, welches ebenso von ihr behandelt wird. - Integer/Enum/Set/ShortString ligt mit drin und braucht nicht extra behandelt zu werden - bei den String, DynArray und Interface macht dieses halt die CompilerMagic, wenn der Record-Speicher Ordnunggemäß freigegeben wird (man kann es aber auch selber machen) - bei Objekten mußt du es mit .Free selber machen (es sei den, das Objekt liegt in einem anderen Objekt, welches seine Liste selber bereinigt) - bei allen anderen Pointern mußt du es eh selber machen |
Re: Richtig/sauber freigeben - nur wie?
Alles klar, ich denke, jetzt hab ichs soweit verstanden ;)
Und was ist mit Pointern wie zB von ScanLine welche kommen? das sind doch eigentlich nur integerwerte, die auf einen Speicherbereich (zB Bitmap) zeigen, der separat freigegeben wird (hier mit dem Objekt vom Typ TBitmap), oder? |
Re: Richtig/sauber freigeben - nur wie?
bei ScanLine holst du dir sozusagen nur eine Kopie eines Zeigers auf den Speicher ... der verwiesene Speicher wird aber vom TBitmap verwaltet und auch freigegeben.
|
Re: Richtig/sauber freigeben - nur wie?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz