[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