Search code examples
memory-leaksfreepascalfpccompiler-bug

Memory leak in Free Pascal caused by methods with 'pointer' parameter


After replacing hard type casts of AnsiString to TBytes (array of string) with a ToBytes method (see below), Delphi reported no memory leaks - Free Pascal 2.6.2 however shows a leak in case the TBytes value is passed to a method with a parameter of type Pointer.

The following code leaks memory:

program project1;

{$mode delphi}

uses
  SysUtils;

function ToBytes(const AValue: AnsiString): TBytes;
begin
  SetLength(Result, Length(AValue)); // <-- leak (ine 10)
  if Length(AValue) > 0 then
    Move(AValue[1], Result[0], Length(AValue));
end;

procedure Send(P: Pointer);
begin

end;

begin
  Send(ToBytes('test'));

  SetHeapTraceOutput('heaptrace.log');
end. 

Memory leak report:

Call trace for block $001C5CC0 size 12   $00401586  TOBYTES,  line 10
of project1.lpr   $00401622  main,  line 21 of project1.lpr

If I change the Send method to take an argument of type TBytes, the memory leak disappears.


Solution

  • That's a compiler bug. The managed type TBytes has reference counted lifetime. The compiler should create an implicit local variable which is assigned the array returned by ToBytes. You'll need to work around that by storing to an explicit local:

    var
      Tmp: TBytes;
    ....
    Tmp := ToBytes(...);
    Send(Tmp);