Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Memory Leak bei FindFirst/TSearchRec trotz FileClose (https://www.delphipraxis.net/127652-memory-leak-bei-findfirst-tsearchrec-trotz-fileclose.html)

crowley 16. Jan 2009 15:39


Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Servus,

ich hab ein Problem mit TSearchRec bzw. FindFirst. Trotz des FileClose tritt bei meinem Code immer noch ein MemoryLeak auf. Ich benutze Delphi 7 und FastMM 4.78

Hier ein ganz rudimentärer Beispiel- Code für eine Konsolenanwendung. Jetzt nicht über den Sinn oder Unsinn dieses Codes diskutieren, das hier dient nur der Veranschaulichung, dass da ein Speicherleck auftritt:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$I common.inc}

uses
  FastMM4 in '..\FastMM\FastMM4.pas',
  SysUtils;

var
  loc_path: String;
  loc_dummy: String;
  loc_sr: TSearchRec;

begin
  loc_path := 'C:\Temp\';
  loc_dummy := 'TestFile.log';
  if FindFirst(loc_path + '*.log', faAnyFile - faDirectory, loc_sr) = 0 then
    try
      repeat
        if (SameText(loc_dummy, loc_sr.Name)) then begin
          Writeln('Found file: ' + loc_sr.Name);
        end;
      until (FindNext(loc_sr) <> 0);
    finally
      FindClose(loc_sr);
    end;

  { Free memory of string vars }
  loc_path := '';
  loc_dummy := '';
end.
FastMM schmeißt folgenden Report raus:

Zitat:

--------------------------------2009/1/16 16:29:18--------------------------------
A memory block has been leaked. The size is: 28

Stack trace of when this block was allocated (return addresses):
402BB4
404265
404290
40A1FC
40A273
40CCF7
7C90DC9C [ZwSetInformationThread]
7C817067 [RegisterWaitForInputIdle]
7C817070 [RegisterWaitForInputIdle]

The block is currently used for an object of class: Unknown

The allocation number is: 97

Current memory dump of 256 bytes starting at pointer address DAB0B0:
01 00 00 00 10 00 00 00 73 76 63 43 41 4C 77 6D 73 52 52 50 2E 6C 6F 67 00 00 B2 50 F8 10 80 80
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
. . . . . . . . s v c C A L w m s R R P . l o g . . ² P ø . € €
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

--------------------------------2009/1/16 16:29:18--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

21 - 28 bytes: String x 1

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".
Hat von Euch jemand eine Idee, wie ich das Loch stopfen kann? Oder hab ich etwas ganz Elementares übersehen?

Lieben Gruß und vielen Dank im Voraus,

C.

nahpets 16. Jan 2009 15:56

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Hallo,

das Loch muss nicht von Dir sein.
Ist es auch noch vorhanden, wenn Du mal diesen Bereich auskommentierst:
Delphi-Quellcode:
if (SameText(loc_dummy, loc_sr.Name)) then begin
  Writeln('Found file: ' + loc_sr.Name);
end;
Ist es auch noch vorhanden, wenn Du die Suche mal komplett auskommentierst?

sirius 16. Jan 2009 16:33

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Ich würde sagen in TSearchrec ist noch eine Referenz auf den String.
Schieb den Code mal in eine Procedure!

crowley 21. Jan 2009 11:38

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Zitat:

Zitat von nahpets
Hallo,

das Loch muss nicht von Dir sein.
Ist es auch noch vorhanden, wenn Du mal diesen Bereich auskommentierst:
Delphi-Quellcode:
if (SameText(loc_dummy, loc_sr.Name)) then begin
  Writeln('Found file: ' + loc_sr.Name);
end;
Ist es auch noch vorhanden, wenn Du die Suche mal komplett auskommentierst?

Das Speicherloch ist auch dann noch da, wenn ich diesen Block auskommentiere o_O
Es reicht das FindFirst, um das Leak zu bekommen.



Zitat:

Zitat von sirius
Ich würde sagen in TSearchrec ist noch eine Referenz auf den String.
Schieb den Code mal in eine Procedure!

Sirius, danke dir... das hat geholfen. Jetzt steht der Code in einer eigenen Prozedur und das Speicherloch ist weg o_O

Union 21. Jan 2009 15:38

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Es liegt daran, dass Du globale Variablen verwendest. Lagerstr Du alles in eine separate Prozedur aus, gibt es kein Speicherleck:
Delphi-Quellcode:
procedure FindLogFiles;
var
  loc_path: String;
  loc_dummy: String;
  loc_sr: TSearchRec;
begin
  loc_path := 'C:\Temp\';
  loc_dummy := 'TestFile.log';
  if FindFirst(loc_path + '*.log', faAnyFile - faDirectory, loc_sr) = 0 then
    try
      repeat
        if (SameText(loc_dummy, loc_sr.Name)) then begin
          Writeln('Found file: ' + loc_sr.Name);
        end;
      until (FindNext(loc_sr) <> 0);
    finally
      FindClose(loc_sr);
    end;
  { Free memory of string vars }
  loc_path := '';
  loc_dummy := '';
end;

begin
   FindLogFiles;
end.
Oder, alternativ mit Finalize(loc_sr).

HJay 16. Dez 2009 18:32

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Als Anfänger mal nachgefragt:

Muss man lokale Variable wirklich so freigeben? Ich dachte, die entfallen am Ende der Prozedur automatisch?!

Delphi-Quellcode:
 { Free memory of string vars }
  loc_path := '';
  loc_dummy := '';

himitsu 16. Dez 2009 18:39

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Neee, muß man nicht ... zumindestens nicht in Delphi.

String (AnsiString/WideString/UnicodeString), dynamische Arrays und Interfaces werden utomatisch freigegeben und vorher auch initialisiert.

Für diese beiden lokalen Strings versteckt sich also in BEGIN (der Prozedur) eine Initialisierung und im END eine Finalisierung aka :='';

HJay 16. Dez 2009 19:11

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Danke, da bin ich aber beruhigt. So hatte ich mir das auch vorgestellt.

Danke!

Christian Seehase 16. Dez 2009 19:45

Re: Memory Leak bei FindFirst/TSearchRec trotz FileClose
 
Moin crowley,

auch wenn der Thread hier fast ein Jahr alt ist... ;-)

Das hier

Delphi-Quellcode:
faAnyFile - faDirectory
sollte man nicht machen.
Um ein Bit, oder mehrere Bits, auszumaskieren sollte man

Delphi-Quellcode:
faAnyFile and not faDirectory
schreiben, um eventuelle, unerwünschte, Seiteneffekte zu verhindern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:13 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