Delphi-PRAXiS
Seite 3 von 9     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Record zurücksetzen (löschen) (https://www.delphipraxis.net/120638-record-zuruecksetzen-loeschen.html)

SubData 14. Sep 2008 13:06

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Hansa
Bei einem Record handelt es sich nunmal NICHT um Pointer etc.

Bei Strings im Record schon (Solange es keine ShortStrings) sind.

alzaimar 14. Sep 2008 13:13

Re: Record zurücksetzen (löschen)
 
FastMM meldet jedenfalls nichts.

Neutral General 14. Sep 2008 13:13

Re: Record zurücksetzen (löschen)
 
Also es sieht laut FastMM4 so aus:

Delphi-Quellcode:
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;
erzeugt KEIN MemoryLeak. Der MemoryManager schafft es wohl trotzdem den String nach der Methode mit dem Record freizugeben.

Anders siehts bei globalen Variablen oder Klassenvariablen aus. Da hinterlässt dieser Code ein MemoryLeak. Aber auch das kann verhindert werden:

Delphi-Quellcode:
Finalize(Beweis);
Diese Zeile vor dem FillChar lässt das MemoryLeak verschwinden.

Delphi-Quellcode:

// 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;
@Hansa:

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.

Popov 14. Sep 2008 13:13

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Guido Eisenbeis
da ich bei meiner Suche nichts gefunden habe, ahne ich, dass ich da selbst Hand angelegt muss. Aber dennoch die Frage: Gibt es eine Delphi-Funktion um ein Record zu löschen? Also sowas wie MyRecord := nil? :gruebel:

Alle Tipps schön und gut, man muß sie sich aber immer merken und bevor man dann stundenlang überlegt wie das war, ein mal machen, immer wieder nutzen können ;)

Delphi-Quellcode:
procedure MyRecordClear;
begin
  with MyRecord do
  begin
    Test_1 := '';
    Test_2 := '';
    Test_3 := '';
    Integer_1 := 0;
    Integer_2 := 0;
  end;
end;
Man sollte sich das Leben einfach machen.

Guido Eisenbeis 14. Sep 2008 13:19

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.

SubData 14. Sep 2008 13:19

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.

Guido Eisenbeis 14. Sep 2008 13:22

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Popov
Alle Tipps schön und gut, man muß sie sich aber immer merken und bevor man dann stundenlang überlegt wie das war, ein mal machen, immer wieder nutzen können ;)

Delphi-Quellcode:
procedure MyRecordClear;
begin
  with MyRecord do
  begin
    Test_1 := '';
    Test_2 := '';
    Test_3 := '';
    Integer_1 := 0;
    Integer_2 := 0;
  end;
end;

Was aber machst du, wenn, wie oben beschrieben, dein Record noch andere Records enthält (z. B. FindData: TWIN32FINDDATA) und die dann wieder weitere Records enthalten, die dann ... ?

Guido.

Neutral General 14. Sep 2008 13:23

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von SubData
@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.

Gleiches Ergebnis wie mit normalen globalen Variablen und Klassenvariablen. Ohne Finalize gibtsn MemoryLeak. Mit gibts keins.

@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.

SubData 14. Sep 2008 13:26

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:

Popov 14. Sep 2008 13:26

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Guido Eisenbeis
Was aber machst du, wenn, wie oben beschrieben, dein Record noch andere Records enthält?

Wird nur etwas länger.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:16 Uhr.
Seite 3 von 9     123 45     Letzte »    

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