![]() |
MemoryLeak beim Befehl New
Hallo zusammen,
ich habe den folgende Inhalt der Procedure im I-Net gefunden und an meine Klasse angepasst :
Delphi-Quellcode:
FAllInfos ist nur eine TList, die im Konstruktor erstellt wird.
procedure TPrinterInfo.GetAllPrinterInfos;
var pcbNeeded : DWORD; pcReturned : DWORD; Buffer : PChar; PrinterInfo: PChar; I : Integer; PPrinter : PPrinterInfo2; Flags : DWORD; Level : Byte; begin if Win32Platform = VER_PLATFORM_WIN32_NT then begin Flags := PRINTER_ENUM_CONNECTIONS or PRINTER_ENUM_LOCAL; Level := 2; end else begin Flags := PRINTER_ENUM_LOCAL; Level := 2; end; EnumPrinters(Flags, nil, Level, nil, 0, pcbNeeded, pcReturned); GetMem(Buffer, pcbNeeded); EnumPrinters(Flags, nil, Level, PByte(Buffer), pcbNeeded, pcbNeeded, pcReturned); PrinterInfo := Buffer; for I := 0 to pcReturned - 1 do begin New(PPrinter); // <--- Hier ist wahrscheinlich das MemoryLeak with PPrinterInfo2(PrinterInfo)^ do begin PPrinter^.pServerName := pServerName; PPrinter^.pPrinterName := pPrinterName; PPrinter^.pShareName := pShareName; PPrinter^.pPortName := pPortName; PPrinter^.pDriverName := pDriverName; PPrinter^.pComment := pComment; PPrinter^.pLocation := pLocation; PPrinter^.pSepFile := pSepFile; PPrinter^.pPrintProcessor := pPrintProcessor; PPrinter^.pDatatype := pDatatype; PPrinter^.pParameters := pParameters; PPrinter^.Attributes := Attributes; PPrinter^.Priority := Priority; PPrinter^.DefaultPriority := DefaultPriority; PPrinter^.StartTime := StartTime; PPrinter^.UntilTime := UntilTime; PPrinter^.Status := Status; PPrinter^.cJobs := cJobs; PPrinter^.AveragePPM := AveragePPM; FAllInfos.Add(Pointer(PPrinter)); Inc(PrinterInfo, SizeOf(TPrinterInfo2)); end; end; FreeMem(Buffer); end; Die Procedure funktioniert auch wunderbar. Es gibt da nur ein kleines Problem. Wenn ich die Klasse mit Eurekalog kompiliere und ausführe, dann zeigt er mir ein MemoryLeak beim Befehl New(PPPrinter) an. Ich habe dann unter FreeMem(Buffer) noch Dispose(PPrinter) hinzugefügt, was aber nicht hilft. Könnte mir das Bitte jemand erklären, warum dann immer noch ein MemoryLeak angezeigt wird. Ich verstehe wahrscheinlich die Darstellung mit den Pointer nicht, trotz das ich mir schon ein paar Tutorials durchgelsen habe. |
Re: MemoryLeak beim Befehl New
Du musst den Zeiger wieder aus der Liste entfernen
|
Re: MemoryLeak beim Befehl New
Welchen Zeiger aus der Liste entfernen ?
Ich rufe die Daten aus der Liste nachher dann so ab :
Delphi-Quellcode:
function TPrinterInfo.GetPrinterName:string;
var PPrinter : PPrinterInfo2; begin result := ''; if FAllInfos.Count <> 0 then begin PPrinter := FAllInfos.Items[FPrinterIndex]; result := PPrinter^.pPrinterName; end; end; |
Re: MemoryLeak beim Befehl New
Das heißt, vor dem Zerstören der Liste musst Du alle enthaltenen Objekte freigeben (von hinten nach vorn). Alternativ könntest Du aber auch eine Klasse aus Deiner Printerinfo machen und dann eine TObjectlist verwenden.
|
Re: MemoryLeak beim Befehl New
FAllInfos
|
Re: MemoryLeak beim Befehl New
Zitat:
Zitat:
Ich verstehe im Moment nur Bahnhof. Ich deklariere doch nur in der Funktion den Pointer PPrinter und zerstöre diesen am Ende der Procedure wieder. |
Re: MemoryLeak beim Befehl New
Du erzeugst eine Struktur und fügst einen Zeiger auf diese in eine Liste ein. Später zerstörst du diese Struktur. Der Zeiger in der Liste zeigt dann auf die nicht mehr existente Struktur.
|
Re: MemoryLeak beim Befehl New
Zitat:
|
Re: MemoryLeak beim Befehl New
Als Faustregel gilt: Pro New ein Dispose. Wenn Du die Liste zerstörst, entfernst Du nur den Verweis auf die Liste selbst, die enthaltenen Items belegen weiterhin Speicher. Also vor dem Free dann:
Delphi-Quellcode:
for i := Pred(Liste.Count) downto 0 do
Dispose(Liste.Items[i]);//evtl. noch ein SizeOf dazu, hab gerade kein Delphi zur Hand |
Re: MemoryLeak beim Befehl New
Danke Detlef, Deine Faustregel hat mir geholfen, es etwas besser zu verstehen. Ich habe jetzt im Destruktor der Klasse TPrinterInfo noch die folgenden Zeilen eingefügt und bekomme keinen MemoryLeak mehr angezeigt.
Delphi-Quellcode:
Danke auch an Dich mkinzler. Habt mir beide sehr weitergeholfen. Jetzt ist der MemoryLeak weg. :spin2:
if FAllInfos.Count > 0 then begin
for I :=0 to FAllInfos.Count -1 do Dispose(FAllInfos[I]); FAllInfos.Clear; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02: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