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

Yuriy Sydorov jura at cp-lab.com
Sat Jan 9 20:12:47 CET 2021


On 09.01.2021 19:23, Bart via fpc-pascal wrote:
> On Sat, Jan 9, 2021 at 5:12 PM Yuriy Sydorov via fpc-pascal
> <fpc-pascal at lists.freepascal.org> wrote:
> 
>>> 2. Is it OK if the elements of the array are (or contain) managed types?
>>
>> You need to manually finalize/free elements which are overwritten before calling Move.
> So, if I move Arr[3] to Arr[1], I first have to finilize/free Arr[1].
> After that move the bytes in Arr[3] are exactly the same as in Arr[1]
> (by definition of how move works) AFAIU.
> Is that a problem with refcounts, because they would be the same also
> but the number of copies increased?

System.Move just copies bytes in the memory. So all handling of managed types must be done manually.
So if Arr[1] contains a managed value you need to finalize/free it before Move.
After move Arr[1] and Arr[3] will contain the same value and if you need to keep both you need to increase the refcount 
manually.

>> Also if you intend to use Move for duplication of elements of managed types, it is better to use for-loop to copy each
>> element separately to allow proper increments of references.
>>
>>> 3. Are there caveats if T is a specialization of a generic type definition?
>>
> 
> Thanks for explaning.
> OK, since this is a generic class, Systme.Move() can be safe, but it
> is not guaranteed (almost by definition you never know what <T> is
> going to be in the specialization.

If your array contains class object instances and no other references to them exist then you need to Free them before 
overwriting by Move.

> So, I'll use a for loop to copy the data.
> 
> I assume that doing Arr[Index] := Default(T) will also finalize the
> element if that element ismanaged?

For class object instances call Arr[Index].Free, for other managed types or records containing managed types 
Finalize(Arr[Index]) should work.

Yuriy.


More information about the fpc-pascal mailing list