[Lazarus] Dangers of using Move command to insert data into a TBytes array?

Michael Van Canneyt michael at freepascal.org
Wed Aug 30 09:48:47 CEST 2017



On Wed, 30 Aug 2017, Bo Berglund via Lazarus wrote:

> I just want to check with you which way is safer when using Move()
> commands in a procedure to combine two TBytes arrays by inserting one
> into the other at a specified point.
>
>
> What I need to do is the following:
> - Increase the size of the Dest array by the length of the Src array
> - Move the data following the insertion point in the Dest array
> towards the end starting at Index
> - Copy the data from the Src array into Dest at Index where the hole
> has been created
>
> Like this:
>
> procedure  InsertBytes(var Dest: TBytes; Src: TBytes; Index: integer);
> var
>  LenD, LenS: integer;
> begin
>  if Length(Src) = 0 then exit;
>  LenD := Length(Dest);
>  LenS := Length(Src);
>  if Index > LenD then Index := LenD;  //Make an append instead
>  SetLength(Dest, LenD + LenS);
>  Move(Dest[Index], Dest[Index + LenS], LenD - Index);  //Create space
>  Move(Src[0], Dest[Index], LenS);  //Insert data
> end;
>
> If the calculation of the number of bytes to move (LenD - Index) for
> some reason is wrong and results in too many bytes being moved, what
> will happen then? Will Move() overwrite whatever is following the Dest
> array in memory?

Yes.

>
> Would it be safer to use a local intermediate array to combine Dest
> and Src and then in the end Move the data back into Dest?

Not really. 
If you calculate lengths wrong, the end result is unpredictable in any case.

>
> I have tested the above procedure and it looks OK, but I am worried
> that in some cases the same kind of construct would be wrong and maybe
> cause unknown side effects.
> I must use Move() for handling other data of various kinds like packed
> records and such too...

If the packed records contain managed data (ansistrings and the like): 
Don't use move.

Michael.



More information about the Lazarus mailing list