'Reason why a freed TStringList counts as memory leak in the FastMM4 report
After noticing an odd memory behavior in task manager in one of my applications I started investigating memory leaks with FastMM4. I found more than 1000 just after opening three forms. I hope I will be able to find the cause in a single place
In one case, even if always free the TStringList in the finally block (that is always reached), FastMM4 reports a memory leak:
function GetMatchingResourceFileName(MatchingString:string) : string;
var
ResourcesList: TStringList;
I : Integer;
begin
Result := '';
try
ResourcesList := TStringList.Create;
// get resource files list
ResourcesList := GetResourceList;
//search for matching file name
for I := 0 to ResourcesList.Count-1 do
begin
if Pos(MatchingString,ResourcesList.Strings[I]) > 0 then
begin
Result := ResourcesList.Strings[I];
break;
end;
end;
finally
ResourcesList.Free;
ResourcesList:= nil;
end;
end;
FastMM4 stack report tells me that the leak starts from
ResourcesList := TStringList.Create;
even if I am 100% sure that ResourcesList.Free; is executed I see the memory leak.
Here you can see that the breakpoint is hit:

As I close the app I see the report:
---------------------------
myProject.exe: Memory Leak Detected
---------------------------
This application has leaked memory. The small-block leaks are (excluding expected leaks registered by pointer):
85 - 100 bytes: System.Classes.TStringList 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".
To study the leak above I commented 99% of my code focus on the first reported leak, in fact, one in the initialization part of the app.
How this is possible?
Update
The working version of the code avoids to call TStringList.Create since the GetResourceList method already returns a properly created TStringList, the following code is now leak free:
function GetMatchingResourceFileName(MatchingString:string) : string;
var
ResourcesList: TStringList;
I : Integer;
begin
Result := '';
try
ResourcesList := GetResourceList;
//search for matching file name
for I := 0 to ResourcesList.Count-1 do
[...]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
