[fpc-pascal] Question about System.Move()

Bart bartjunk64 at gmail.com
Wed Jan 13 17:29:55 CET 2021


On Sun, Jan 10, 2021 at 12:09 PM Sven Barth via fpc-pascal
<fpc-pascal at lists.freepascal.org> wrote:

> If after the Move only one of the two references is reachable anymore
> (because e.g. some internal count variable "ends" the array before that
> element) then you don't need to care about increasing the reference
> count, cause there is only one reference after all (in that case you
> must *not* use an assignment to clear the value, but e.g. FillChar,
> cause the reference count must not be touched). Only if you'd really
> duplicate the element you'd need to take care of that.

I came up with this:

Assume that:
FData is defined as Array of T (T being generic)

  procedure MoveDataManaged(StartIndex: SizeUInt; Offset: SizeInt;
NrElems: SizeUInt);
  var
    i: SizeUInt;
  begin
    if Offset>0 then
    begin
      for i := StartIndex + NrElems-1 downto StartIndex do
      begin
        if IsManagedType(T) then //finalize before overwriting
          Finalize(FData[i+Offset]);
        FData[i+Offset] := FData[i];
        if IsManagedType(T) then
          Finalize(FData[i]);
        FillChar(FData[i], SizeOf(T), 0); //erase old data, not
necessary after finalize
      end;
    end
    else
    begin
      for i := 0 to NrElems-1 do
      begin
        if IsManagedType(T) then
          Finalize(FData[StartIndex+i+Offset]);
        FData[StartIndex+i+Offset] := FData[StartIndex+i];
        if IsManagedType(T) then
          Finalize(FData[StartIndex+i]);
        FillChar(FData[StartIndex+i], SizeOf(T), 0);
      end;
    end;
  end;

I tested this with T being Array of Char (so FData being an array of
array of Char).
Leaving out any of the Finalize statements will make HeapTrace barf at
me about unfreed memory blocks.

Does it make any sense?
--
Bart


More information about the fpc-pascal mailing list