Einzelnen Beitrag anzeigen

BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Hilfe bei Speicherleckbeseitigung

  Alt 29. Jul 2009, 09:35
Hallo und guten Morgen an alle DP´ler,

Ich bräuchte mal eure Hilfe. Ich bin jetzt schon einige Tage dabei mich genauer mit Speicherlecks in meinem Programm zu beschäfftigen. Leider gibt es hier einige Startschwierigkeiten. Vorallem machen mir die Speicherlecks zu schaffen, die in Folge von TStringLists entstehen.
Gut zu Kern der Geschichte:
Ich habe mir mal eine kleine Funktion herausgesucht, bei der genau die Problematik besteht
Delphi-Quellcode:
unit FestplattenArbeit;

interface

uses Windows, SysUtils, Classes;

Type TFestplattenArbeit = class(TComponent)
  private
    FsLInfoeinfachLaufwerke: TStringList;
    function DriveExists(DriveByte: Byte): Boolean;
    procedure simpleDriveSearch(var LaufwerkList: TStringList);
    function GetLaufwerksanzahl: integer;
  protected
  public
    constructor create(AOwner: TComponent); reintroduce;
    destructor Destroy; //override;
    property Count: integer read GetLaufwerksanzahl;
    property FestplattenListe: TStringlist read FsLInfoeinfachLaufwerke;
end;

implementation

{////////////////////////////////////////////////////////////////////////////////////}
{/                              create und destroys                                 /}
{////////////////////////////////////////////////////////////////////////////////////}

constructor TFestplattenArbeit.create(AOwner: TComponent);
begin
  inherited create(AOwner);
  FsLInfoeinfachLaufwerke := TStringList.Create;
  simpleDriveSearch(FsLInfoeinfachLaufwerke);
end;

destructor TFestplattenArbeit.destroy;
begin
  while FsLInfoeinfachLaufwerke.Count > 0 do FslInfoeinfachLaufwerke.Delete(0);
  FsLInfoeinfachLaufwerke.Free;
  inherited destroy;
end;

{////////////////////////////////////////////////////////////////////////////////////}
{/                              private Funktionen                                  /}
{////////////////////////////////////////////////////////////////////////////////////}

function TFestplattenArbeit.DriveExists(DriveByte: Byte): Boolean;
begin
  Result := GetLogicalDrives and (1 shl DriveByte) <> 0;
end;

procedure TFestplattenArbeit.simpleDriveSearch(var LaufwerkList: TStringList);
var Index: Integer;
begin
  for Index := 0 to 25 do if DriveExists(Index) then LaufwerkList.Add(Chr(Index + Ord('A')) + ':\');
end;

{////////////////////////////////////////////////////////////////////////////////////}
{/                              Getter und Setter                                   /}
{////////////////////////////////////////////////////////////////////////////////////}

function TFestplattenArbeit.GetLaufwerksanzahl: integer;
begin
  result := FsLInfoeinfachLaufwerke.Count;
end;

end.
Crosspost: Hier wurde schonmal ein Teil der Unit gepostet.

Diese Unit verursacht bei mir genau 8 Speicherlecks (Diese 8 Fehler ergeben sich aufgrund der Anzahl an gefundenen Fesplatten!! kann also im Einzelfall auf anderen Rechnern variieren). Wie DeddyH im Crosspost richtig bemerkt hat, stammen die nicht wie von mir vermutet von der DriveExist-Funktion, sondern sind mit der TStringList direkt verbunden. Allerdings stoße ich hier erstmal auf gewisse Grenzen, wie ich diese Fehler korrigieren kann.
Aus anderen Threats habe ich mitbekommen, dass man bevor die TStringlist freigegeben werden kann, alle "Einzeleinträge" löschen/ freigeben muss (dies erscheint auch logisch da anscheinend jeder Eintrag an sich schon ein Objekt darstellt und somit je mehr Einträge/ Objekte in meiner Liste sind, desto mehr Speicherlecks habe ich). Die Frage ist eigentlich jetzt und dies habe ich irgendwie noch nirgends als richtigen "Lösungsweg" gefunden, Wie gebe ich die Einträge in einer TStringList richtig frei, damit das TStringlist.free ebenfalls meine Liste freigeben kann?

Folgendes habe ich schonmal versucht:
Delphi-Quellcode:
  // Versuch jeden einzelnen Beitrag zu löschen, bis keiner mehr da ist -> wirkungslos, Fehlerzahl bleibt konst
  while FsLInfoeinfachLaufwerke.Count > 0 do FslInfoeinfachLaufwerke.Delete(0);
  // Versuch die gesamte Liste zu löschen -> wirkungslos, Fehlerzahl bleibt konst
  FsLInfoeinfachLaufwerke.clear;
Eine Alternative, bei der ich aber noch nicht weiß, wie man sie einsetzen kann, wäre wohl eine TObjectList. Diese schien bei vielen Threats die einzige Lösung zu sein um kein Speicherleck zu erzeugen. Aber dort bleibt für mich die Frage, ist sowas wirklich nötig/ sinnvoll, wenn ich nur eine Problemursache habe, etwas neues für die Verwaltung diese Objektes aufzumachen? Allerdings würde mich schon (für meine größeren Units) mal interessieren, wie sowas aussieht.

Vielen Dank
BAMatze
2. Account Sero
  Mit Zitat antworten Zitat