[fpc-devel] Redefine FillChar() to use out parameter instead

Martin lazarus at mfriebe.de
Thu Nov 19 10:20:46 CET 2009


Jonas Maebe wrote:
> Alexander Klenin wrote on do, 19 nov 2009:
>> Can you give an example code which would be (badly) affected by 
>> proposed change?
>
> type
>   tr = record
>     str: ansistring;
>   end;
>
> procedure clear(out rec; size: ptruint);
> begin
>   fillchar(rec,size,0);
> end;
>
> var
>   r: tr;
> begin
>   r.str:=paramstr(0);
>   clear(r);
> end.
>
> If you change the behaviour of "out" so that such parameters are no 
> longer finalised before the routine is entered, then the above will 
> cause a memory leak. You can verify this by changing the "out rec" 
> parameter into "var rec".

Well in this case, the code is actually positively affected by the "out" 
param (because it avoids the mem leak)

But if you ever handled ref-counted data by hand.....

type TStringArray = Array of string;

procedure InsertOne(a: TStringArray);
var l : integer;
begin
  l := length(a)
  SetLength(a, l + 1)
  Move(a[0], a[1], l*SizeOf(String));
  // now a[0] and a[1] point to the same string
  // but the string has still a ref-count of 1
  // so assigning a[0] := nil => would release the memory used by a[1]
  FillChar(a[0], SizeOf(String), 0);
end;

the above works, because Filchar has a var param. otherwise it would 
finalize the string, and a[1] would point to released memory....

Similar case happen, if your array was filled with random, none zero 
data, and now need to be accessed via string functionality. The only way 
to set the entries to 0 is FillChar. If you use a[]:=nil while a[0] has 
random data, then it would attempt to free the string at the random 
location , and that would crash since there is no string

Martin








More information about the fpc-devel mailing list