Delphi compiler record memory leak

Viewed 134

I realise this is a contrived example but the following code causes a memory leak in Delphi XE2 (and maybe other versions).

type
  TTest =record
    a :string;
    procedure SetA;
  end;

procedure TTest.SetA;
begin
  a:='Test';
end;

procedure TfrmMain.btGoClick(Sender: TObject);
var
  t :TTest;

  procedure SetA(const Rec: TTest);
  begin
    Memo.Lines.Add(IntToStr(NativeInt(@Rec)));

    Rec.SetA;
  end;

begin
  Memo.Lines.Add(IntToStr(NativeInt(@t)));

  SetA(t);

  if t.a='' then
    Memo.Lines.Add('t.a: (empty)')
  else
    Memo.Lines.Add('t.a: '+t.a);
end;

The source of the memory leak is the setting of a in TTest.SetA, the string is never released.

The output of the above is:

1700728
1700688
t.a: (empty)

From this we can see that even though the record parameter is passed as a const the address of Rec is different from the main variable t.

Now if I change the record type definition to:

  TTest =record
    a :string;
    a1 :string;
    a2 :string;
    a3 :string;
    procedure SetA;
  end;

The output is now:

1700712
1700712
t.a: Test

So the same address of Rec and t, also t.a has been set, also no memory leak.

I have tried to look at the CPU but have a hard time seeing the difference when the dummy a1, a2 and a3 variables are added.

Obviously all this can be avoided by making the parameter to SetA a var parameter, but the reason for this question is to try and understand what the compiler is doing in the two different situations.

So what is going on here?

0 Answers
Related