![]() |
Record "finalisieren"
Gemeinde.
Es tut mir schrecklich leid, wenn ich nicht die richtigen Ausdrücke und Worte finde für mein Problem. Ich habe ein packed Record, etwa so:
Delphi-Quellcode:
und folgendermaßen erzeuge ich einen neuen Datensatz, wenn erforderlich und speichere ihn/einen Verweis zum ihm (?) in einer TList:
type
PData = ^TData; TData = packed record sBeispielVar: String; end;
Delphi-Quellcode:
Zuvor habe ich einen Eintrag mit
var
Data: PData: begin New(Data); Data^.sBeispielVar := 'Test'; DataList.Add(Data); end;
Delphi-Quellcode:
gelöscht und Data finalisiert:
DataList.Delete(X);
Delphi-Quellcode:
.
finalize(Data^);
Aber finalize scheint nicht thread-safe zu sein. Die Frage ist: wird bei
Delphi-Quellcode:
der komplette Datensatz Data, der an dieser Stelle X gespeichert ist, mit gelöscht?
DataList.Delete(X);
|
AW: Record "finalisieren"
Hallo,
Bedenke dass du auch Dispose aufrufen musst (oder macht das die Liste beim Delete?). Wie ich es machen würde:
Code:
Finalize(DataList[X]^);
Dispose(DataList[X]); DataList.Delete(X); |
AW: Record "finalisieren"
Dispose ruft übrigens intern schon von sich aus Finalize auf, hatte ich glaub ich mal rausgefunden.
|
AW: Record "finalisieren"
Sehr interessant. Das scheint wunderbar, selbst im TThread, zu funktionieren.
Warum war denn Finalize(Data^) falsch? Ich habe mit mal den Code von Dispose rausgesucht:
Delphi-Quellcode:
Finalize ist wirklich vertreten, aber mit einer Bedingung verknüpft.
procedure _Dispose(P: Pointer; TypeInfo: Pointer);
{$IFDEF PUREPASCAL} begin _Finalize(P, TypeInfo); FreeMem(P); end; {$ELSE} asm { -> EAX Pointer to object to be disposed } { EDX Pointer to type info } {$IFDEF ALIGN_STACK} SUB ESP, 8 {$ENDIF ALIGN_STACK} PUSH EAX CALL _Finalize POP EAX {$IFDEF ALIGN_STACK} SUB ESP, 4 {$ENDIF ALIGN_STACK} CALL _FreeMem {$IFDEF ALIGN_STACK} ADD ESP, 12 {$ENDIF ALIGN_STACK} end; {$ENDIF !PUREPASCAL} Und in der selben Unit wird, wenn Dispose(P); aufgerufen wird, auch niemals Finalize aufgerufen. Demnach scheint Finalize wirklich immer aufgerufen zu werden, wenn man Dispose aufruft. |
AW: Record "finalisieren"
GetMem und FreeMem = ohne Initialize und Finalize
New und Dispose = mit Initialize und Finalize Setzt Finalize den Speicher eigentlich auch auf 0/nil, oder gibt es die verlinkten Speicher "nur" frei? Wenn nicht auf nil gesetzt wird, dann ist ein "doppelter" Aufruf von Finalize falsch und kann/wird zu netten Fehlern führen. Welche Delphi-Version? (es kann nie schaden das im Profil anzugeben, oder zumindestens in den Posts) Ab D2009 könnte man auch eine generischen Liste verwenden und das New/Dispose wegzulassen. Jenachdem wie oft die Records umgeschaufelt oder später verändert werden. Da hier eh mit Pointer gearbeitet wird und wenn das "jenachdem" nicht zutrifft, dann doch eher eine generische Liste, mit einem Data-Objekt, statt dem Record. Zitat:
Delphi-Quellcode:
Data.sBeispielVar
|
AW: Record "finalisieren"
[edit] Doppelpost gelöscht
|
AW: Record "finalisieren"
Zitat:
|
AW: Record "finalisieren"
Ich glaube das Problem war dass er Dispose einfach gar nicht aufgerufen hat.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz