AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

MemoryLeak beim Befehl New

Ein Thema von RWarnecke · begonnen am 7. Sep 2008 · letzter Beitrag vom 7. Sep 2008
Antwort Antwort
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#1

MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:28
Hallo zusammen,

ich habe den folgende Inhalt der Procedure im I-Net gefunden und an meine Klasse angepasst :
Delphi-Quellcode:
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;
FAllInfos ist nur eine TList, die im Konstruktor erstellt wird.

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.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:32
Du musst den Zeiger wieder aus der Liste entfernen
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#3

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:34
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;
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:35
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.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:36
FAllInfos
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#6

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:42
Zitat von DeddyH:
Das heißt, vor dem Zerstören der Liste musst Du alle enthaltenen Objekte freigeben (von hinten nach vorn).
Ich dachte, dass würde ich schon machen, indem ich das Dispose(PPrinter) entweder vor FreeMem(Buffer) oder danach reinschreibe.
Zitat von DeddyH:
Alternativ könntest Du aber auch eine Klasse aus Deiner Printerinfo machen und dann eine TObjectlist verwenden.
Ich habe doch schon eine Klasse, die TPrinterInfo heist.

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.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:43
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.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#8

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:51
Zitat von mkinzler:
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.
Es ist aber egal, ob ich das Dispose einfüge oder nicht, ich kann dann trotzdem noch meine Daten aus der Struktur von FAllInfos auslesen, wie ich es im Beitrag #3 geschrieben habe. Im Destruktor der Klasse TPrinterInfo habe ich dann FAllInfos.Free stehen. Damit zerstöre ich doch dann alles oder nicht ?
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:52
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
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#10

Re: MemoryLeak beim Befehl New

  Alt 7. Sep 2008, 10:59
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:
  if FAllInfos.Count > 0 then begin
     for I :=0 to FAllInfos.Count -1 do Dispose(FAllInfos[I]);
     FAllInfos.Clear;
  end;
Danke auch an Dich mkinzler. Habt mir beide sehr weitergeholfen. Jetzt ist der MemoryLeak weg.
Rolf Warnecke
App4Mission
  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 05:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz