AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Verständnisfrage Memory-Leak einfacher String
Thema durchsuchen
Ansicht
Themen-Optionen

Verständnisfrage Memory-Leak einfacher String

Ein Thema von Pfoto · begonnen am 9. Sep 2008 · letzter Beitrag vom 9. Sep 2008
Antwort Antwort
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#1

Re: Verständnisfrage Memory-Leak einfacher String

  Alt 9. Sep 2008, 11:06
Delphi gibt die Strings an sich schon frei, sobald du aber mit Pointern auf Strings arbeitest, wirds haarig.

Mit folgendem Code bekommt man leicht ein Memory-Leak, obwohl man im OnDestroy die Pointer wieder freigibt.
Delphi-Quellcode:
var
  aList : TList;

procedure TForm1.FormCreate(Sender: TObject);
var p: PString;
    i: integer;
begin
  aList := TList.Create;

  for i:=0 to 10 do
  begin
    New(p);
    p^ := 'Test - 123';
    aList.Add(p);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var p: PString;
    i: integer;
begin
  for i:=0 to aList.Count-1 do
  begin
    p := aList[i];
    // mit Dispose wird zwar der Pointer wieder freigegeben, aber
    // der Inhalt ('Test - 123') vom Anfang wird nicht wieder
    // Freigegeben.
    Dispose(p);
  end;
  aList.Clear;
  aList.Free;
end;
Das Memory-Leak kann man umgehen, wenn man z.B. vor dem Dispose(p) in Zeile 28 folgende Zeile einfügt
Delphi-Quellcode:
{ ... }
    p^ := ''; // hiermit wird der String an sich wieder freigegeben
    Dispose(p);
  end;
{ ... }
Allgemein hat Delphi auch eine Funktion dafür: Finalize();
Aus der Delphi-Hilfe:
Zitat:
procedure Finalize(var V [; Count: Integer] );

Beschreibung
Finalize sollte nur in Delphi-Quelltext verwendet werden, in dem eine dynamisch erstellte Variable nicht mit der Prozedur Dispose freigegeben wird. Der von dynamische Arrays belegte Speicher kann mit der Prozedur Dispose nicht freigegeben werden. Dynamische Arrays müssen dazu an Finalize übergeben werden.
Beim Freigeben von globalen Variablen, lokalen Variablen, Objekten und dynamischen Variablen mit Dispose generiert der Compiler Programmcode, um alle in der Variablen enthaltenen langen Strings, Varianten und Schnittstellen zusammen mit der Instanz zu finalisieren.
Wenn auf eine dynamische Variable folgende Bedingungen zutreffen
  • Die Variable wird nicht mit der Standardprozedur Dispose (sondern z.B. mit FreeMem) freigegeben.
  • Die Variable enthält lange Strings, Varianten und Schnittstellen, die nicht alle leer sind bzw. den Wert Unassigned haben
Finalize setzt einfach alle langen Strings auf einen leeren Wert und alle Varianten und Schnittstellen auf Unassigned und sorgt somit für die ordnungsgemäße Freigabe des betreffenden Speichers.
Werden mehrere Variablen in einem zusammenhängenden Speicherblock freigegeben (z.B. ein dynamisches String-Array), kann der optionale Parameter Count angegeben werden, um alle Variablen in einer Operation zu deinitialisieren.
Enthält die als Parameter an Finalize übergebene Variable keine langen Strings, Varianten oder Schnittstelle entfernt der Compiler den Aufruf und generiert keinen Code.
Das ist jetzt nur eine Beschreibung, wie mir Strings Memory-Leaks entstehen können.
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 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