Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-03

FillChar/FillByte and Finalize()

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Krzysztof

Hi,

Should I (and in which case) call Finalize() when using FillChar/FillByte? Heaptrc unit is not detecting any memory leak. For example:

type
  PMyRec = ^TMyRec;
  TMyRec = record
    Field1: Int64;
    Field2: String;
    Field3: Int64;
    Field4: String;
    Field5: Boolean;
  end;
procedure push(ARec: PMyRec);
begin
  writeln(ARec^.Field2,',', ARec^.Field4);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  FillChar(f, SizeOf(TMyRec), 0);
  f.Field1 := 1;
  f.Field2 := 'abc';
  push(@f);
  FillChar(f, SizeOf(TMyRec), 0);
  f.Field1 := 2;
  f.Field2 := 'vbnj';
  push(@f);
end;

Regards

Olivier Sannier
to Krzysztof
Krzysztof wrote 35 lines
Hi, Should I (and in which case) call Finalize() when using FillChar/FillByte? Heaptrc unit is not detecting any memory leak. For example: type PMyRec = ^TMyRec; TMyRec = record Field1: Int64; Field2: String; Field3: Int64; Field4: String; Field5: Boolean; end; procedure push(ARec: PMyRec); begin writeln(ARec^.Field2,',', ARec^.Field4); end; procedure TForm1.Button1Click(Sender: TObject); begin FillChar(f, SizeOf(TMyRec), 0); f.Field1 := 1; f.Field2 := 'abc'; push(@f); FillChar(f, SizeOf(TMyRec), 0); f.Field1 := 2; f.Field2 := 'vbnj'; push(@f); end; Regards

Well, looking at your example, all strings are coming from constants in the source code, thus no reference counting takes place because no memory allocation was needed.
However, if you were to do something like this, I believe it would leak:

   f.Field1 := 1;
   f.Field2 := 'abc' + IntToStr(f.Field1);

This way, you are creating a true string instance, and overwriting the pointer with zeroes won't call Finalize.

Krzysztof
to Olivier Sannier

Indeed! This code need finalize() now because heaptrc detect memory leak:

procedure TForm1.Button1Click(Sender: TObject);
var f: TMyRec;
begin
  FillChar(f, SizeOf(TMyRec), 0);
  f.Field1 := 123;
  f.Field2 := 'abc'+IntToStr(f.Field1);
  push(@f);
  system.Finalize(f);
  FillChar(f, SizeOf(TMyRec), 0);
  f.Field1 := 456;
  f.Field2 := 'vbnj'+IntToStr(f.Field1);
  push(@f);
end;

Although, leak is only when FillChar is called again. For example this is not leak:

procedure TForm1.Button1Click(Sender: TObject);
var f: TMyRec;
begin
  FillChar(f, SizeOf(TMyRec), 0);
  f.Field1 := 123;
  f.Field2 := 'abc'+IntToStr(f.Field1);
  push(@f);
  f.Field1 := 456;
  f.Field2 := 'vbnj'+IntToStr(f.Field1);
  push(@f);
  f.Field1 := 789;
  f.Field2 := 'zzzz'+IntToStr(f.Field1);
  push(@f);
end;

Thanks Olivier for explanation