![]() |
Re: Record zurücksetzen (löschen)
Zitat:
|
Re: Record zurücksetzen (löschen)
FastMM meldet jedenfalls nichts.
|
Re: Record zurücksetzen (löschen)
Also es sieht laut FastMM4 so aus:
Delphi-Quellcode:
erzeugt KEIN MemoryLeak. Der MemoryManager schafft es wohl trotzdem den String nach der Methode mit dem Record freizugeben.
type
TBeweis = packed record EinString: String; Zahl: Integer; end; procedure TForm1.Button1Click(Sender: TObject); var Beweis: TBeweis; p: Pointer; begin Beweis.EinString:= 'Test'; p := @Beweis.EinString[1]; FillChar(Beweis,SizeOf(TBeweis),0); ShowMessage(PChar(p)); end; Anders siehts bei globalen Variablen oder Klassenvariablen aus. Da hinterlässt dieser Code ein MemoryLeak. Aber auch das kann verhindert werden:
Delphi-Quellcode:
Diese Zeile vor dem FillChar lässt das MemoryLeak verschwinden.
Finalize(Beweis);
Delphi-Quellcode:
@Hansa:// Globale- oder Klassenvariable var Beweis: TBeweis; procedure TForm1.Button1Click(Sender: TObject); var p: Pointer; begin Beweis.EinString:= 'Test'; p := @Beweis.EinString[1]; Finalize(Beweis); // <--- FillChar(Beweis,SizeOf(TBeweis),0); ShowMessage(PChar(p)); end; Ich weiß, dass es sich bei Records nicht um Pointer handelt. Aber das hat nichts damit zu tun. Fakt ist, dass mit FillChar nur der Pointer zu dem eigentlichen String überschrieben wird. Der String selbst liegt weiterhin im Speicher! Daran ist nichts zu rütteln. |
Re: Record zurücksetzen (löschen)
Zitat:
Delphi-Quellcode:
Man sollte sich das Leben einfach machen.
procedure MyRecordClear;
begin with MyRecord do begin Test_1 := ''; Test_2 := ''; Test_3 := ''; Integer_1 := 0; Integer_2 := 0; end; end; |
Re: Record zurücksetzen (löschen)
Damit keine Missverständnisse auftreten:
Der (die) String(s) sollen KEINESFALLS freigegeben werden! Im Gegenteil: Sie werden ja in meinem Programm benötigt! Sie sollen lediglich auf leer (, Integer auf 0, ...) gesetzt werden! (Speicherplatz soll beibehalten weren.) Der "Beweis" von Neutral General beweist nur, dass der Bereich im Speicher noch die Werte beinhaltet. Das ist ja auch in Ordnung. Ich gehe davon aus, dass FillChar nur die Länge(nangabe) des Strings auf 0 setzt. Das entspräche einem leeren String = gewünschtes Ergebnis. Speicherleck kann ich mir nicht vorstellen, da der Platz ja reserviert bleiben soll, bis die Record-Variable am Programm-Ende freigegeben wird. Guido. |
Re: Record zurücksetzen (löschen)
@Michael: Kannst du das mal mit einer globalen ThreadVar Variable testen?
Einmal mit Finalize und einmal ohne. Edit: @Guido: Das siehst du leider ein wenig falsch. Damit wird der Pointer auf den eigentlichen String überschrieben. Das bedeutet aber nicht, dass bei einer neuen Zuweisung der String wieder an der selben Stelle im Speicher liegt. Dementsprechend wird auch nicht die Längenangabe vom String auf 0 gesetzt, sondern der Pointer zum String. |
Re: Record zurücksetzen (löschen)
Zitat:
Guido. |
Re: Record zurücksetzen (löschen)
Zitat:
@Guido Eisenbeis: FillChar bewirkt schon, dass die Strings leer sind (leer darum, weil der Pointer zum String jetzt irgendwohin zeigt, wo kein String liegen wird). Aber wenn du das machst, musst/solltest du vorher Finalize(Record) aufrufen. Ansonsten gibt es wie gesagt ein MemoryLeak bei globalen (Thread) Variablen und Klassenvariablen. |
Re: Record zurücksetzen (löschen)
Danke!
Ich hab nämlich mal die böse Erfahrung gemacht, dass ich ThreadVar Records am Ende des Threads wieder explizit löschen muss, da sonst die Strings im Record MemoryLeaks verursachen. Den Fehler muss man erstmal finden :roll: |
Re: Record zurücksetzen (löschen)
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:00 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