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