Serhiy
Serhiy

Reputation: 31

record and memory leak

Could you help me please to solve this problem. Here is my code. I Store (in this example) 10000 strings and when I try to delete them only some amount of memory is freed the rest leaks.

type
  PMyData = ^TMyData;
  TMyData = record
  Name:    string;
end;
////////

var
XList:Tlist;
//////////

// Here is how I add//
var
 MyData: PMyData;
 I:Integer;
begin
 for I:=0 to 10000 do begin
 New(MyData);
  MyData.Name:='Hello';
   XList.Add(TObject(MyData));
  end;
end;


///Here is how I delete///
var
 MyData: PMyData;
 I:Integer;
begin
 for I:= XList.Count - 1 downto 0 do begin
 MyData:=PMyData (XList[I]); /// I also used (XList.Items[I])  but the result is the same
  Dispose(MyData);
    XList.Delete(I);
end;

Upvotes: 3

Views: 2538

Answers (7)

Eduardo
Eduardo

Reputation: 7851

Try:

FreeAndNil(XList.Items[I]); 
XList.Delete(I);

Upvotes: 0

Pham
Pham

Reputation: 51

Anytime a record pointer contains a Variant Unbound array such as ... array of ... string except short string type interface you need to call Finalize to free such data before doing a FreeMem or Dispose. Otherwise use class is better

Cheers

Upvotes: 0

Pham
Pham

Reputation: 51

Call below function before Dispose or change record to class(TObject)

Finalize(MyData^);

Cheers

Upvotes: 0

Francesca
Francesca

Reputation: 21640

As far as I can tell, this code is not leaking, provided you effectively execute the clean up code.
The only way to tell if your code is leaking is by asking the Memory Manager to report any leak by adding this instruction somewhere in your code (be sure it's executed):

 ReportMemoryLeaksOnShutdown := True;

The Memory Manager will tell if any of the memory requested by your code is not freed when the application terminates, i.e. YOUR CODE has a leak.
After that, it is the Memory Manager's job to give back the memory to the OS upon termination, and it does it correctly.

Now as to why TaskManager reports more memory apparently not freed when the number of strings increases, it's because the Memory Manager does not relinquish all previously requested memory to the OS as soon as the strings are freed, in case it's needed again later; to avoid requesting again from the OS, it keeps it.

As stated in other answers, TaskManager is not a good tool to spot memory leaks...

Upvotes: 5

Loren Pechtel
Loren Pechtel

Reputation: 9093

Windows task manager isn't a reliable measure of memory use. Use the FastMM4 memory manager with leak tracing turned on.

Upvotes: 5

Remy Lebeau
Remy Lebeau

Reputation: 597215

I see no leak in that code. How are you determining that a leak is occuring? Are you looking at Task Manager? If so, then that is not a reliable way to detect memory leaks. The VCL memory manager does not release freed memory back to the OS, it is cached for later re-use. Task Manager displays allocated memory. It has no concept of how that memory is actually managed by applications.

Upvotes: 6

Mason Wheeler
Mason Wheeler

Reputation: 84640

Your code looks good. What exactly do you mean, only some memory is freed and the rest leaks? Are you getting memory leak reports from FastMM, or are you just not seeing the memory used counter in Task Manager go all the way back down?

If you're not seeing your program give all the memory back, that's by design. It keeps some of it around so that if you allocate more memory it doesn't have to ask for more back from Windows immediately, which helps improve performance. The memory is only "leaked" if the memory manager hasn't actually reclaimed it.

Upvotes: 3

Related Questions