![]() |
Hilfe bei Speicherleckbeseitigung
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:
Crosspost:
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. ![]() 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:
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.
// 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; Vielen Dank BAMatze |
Re: Hilfe bei Speicherleckbeseitigung
Zitat:
hat es einen Grund warum du das override auskommentiert hast? Wenn ich das override hinmache gibts bei mir keinen Speicherleck. Was soll der auch 'destroyen' wenn der etwas falsches inherited? Edit: Wenn du override wegläst, optimiert mir der Compiler das inherited komplett weg... |
Re: Hilfe bei Speicherleckbeseitigung
€: mleyen war schneller
|
Re: Hilfe bei Speicherleckbeseitigung
Ah danke, war genau das richtige. Das auskommentieren stammt eigentlich noch von einem anderen Versuch, dumm das :evil: .
Vieleicht hat aber jemand doch noch eine Antwort auf die Frage mit der TObjectList. Banke für die schnelle Hilfe. |
Re: Hilfe bei Speicherleckbeseitigung
Hallo,
TObjectList verwaltet Objekte und gibt sie beim Free auch frei (wenn OwnsObjects True ist). Heiko |
Re: Hilfe bei Speicherleckbeseitigung
Zitat:
Delphi-Quellcode:
und dann (z.B. im FormCreate):TSingle = class(TObject) Datum : string; Uhrzeit : string; Name : string; Rufnummer : string; end; TMyObjectList = class(TObjectList) private FKeineAhnung: integer; public property KeineAhnung: integer read FKeineAhnung write FKeineAhnung; end;
Delphi-Quellcode:
Nicht vergessen, die Liste beim Schließen wieder freizugeben:
MyObjectList:= TMyObjectList.Create;
Delphi-Quellcode:
Füllen mit:
MyObjectList.Free;
Delphi-Quellcode:
Auslesen mit:
var Single: TSingle;
begin for x:= 1 to 10 do begin Single:= TSingle.Create; Single.Datum:= ... Single.Uhrzeit:= ... MyObjectList.Add(Single); end; end;
Delphi-Quellcode:
Gruß, Carsten
var Single: TSingle;
begin Single:= MyObjectList.Items[0] as TSingle; end; |
Re: Hilfe bei Speicherleckbeseitigung
@carsten jupp das war´s was mich mal interessiert hat :mrgreen:
thanks |
Re: Hilfe bei Speicherleckbeseitigung
Delphi-Quellcode:
Die Schleife ist überflüssig, um die Freigabe der Strings kümmert sich die TStringList im Destructor selbst. Ebenso kümmert sich die TObjectList um die Freigabe der enthaltenen Objekte, wenn OwnsObjects = True (Standard).
while FsLInfoeinfachLaufwerke.Count > 0 do FslInfoeinfachLaufwerke.Delete(0);
FsLInfoeinfachLaufwerke.Free; |
Re: Hilfe bei Speicherleckbeseitigung
Hallo,
warum
Delphi-Quellcode:
und nicht
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;
Delphi-Quellcode:
Stringliste und Prozedur gehören doch zu einer Klasse, da muss die Stringliste doch nicht als Parameter an die Prozedur übergeben werden.
procedure TFestplattenArbeit.simpleDriveSearch;
var Index: Integer; begin for Index := 0 to 25 do if DriveExists(Index) then FslInfoeinfachLaufwerke.Add(Chr(Index + Ord('A')) + ':\'); end; Oder habe ich da was übersehen? |
Re: Hilfe bei Speicherleckbeseitigung
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 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 by Thomas Breitkreuz