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.
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);
It is probably not a bug where you think it is. The heap tracing of FPC has known issues with tracking temps (and automated types in general) in main programs (the main .dpr begin..end).
Move the code to a procedure, and call that from the main begin..end. and you'll see the leak disappears.
This because the general structure of the main program is like
begin
initializeunits(); // procedure call inserted by the compiler
<actual mainprogram statements>
finalizeunits(); // procedure call inserted by the compiler
end.
with the releasing of mainprogram temps happening at "end." after finalizeunits that finalizes the heaptracking. (even if it is first unit, it is still only an unit). So heaptrc misses that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With