Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to copy data from TBytes to Array of Byte in Delphi

Tags:

delphi

pascal

Given the following:

LBytes: TBytes;
LArr: array[1..512] of Byte;
...
SetLength(LBytes, 512);

What is the correct Move() call to copy all bytes from LBytes to LArr?

Move(LBytes[0], LArr, Length(LBytes)); // works

Move(LBytes[0], LArr[1], Length(LBytes)); // works, too

Move(LBytes, LArr[1], Length(LBytes)); // fail

Can someone explain why it makes no difference between using Larr and Larr[1] but makes a difference between LBytes[0] and LBytes?

like image 673
cytrinox Avatar asked Sep 03 '15 12:09

cytrinox


1 Answers

Can someone explain why it makes no difference between using Larr and Larr1 but makes a difference between LBytes[0] and LBytes?

That's because LBytes is a dynamic array which is, ultimately, a pointer to the array. On the other hand, LArr is the array.

Another way to say this is that dynamic arrays are reference types, and fixed length arrays are value types.

In my book, there are two viable ways to do this:

Assert(Length(LBytes)<=Length(LArr));
Move(LBytes[0], LArr, Length(LBytes));

or

Assert(Length(LBytes)<=Length(LArr));
Move(Pointer(LBytes)^, LArr, Length(LBytes));

I prefer the latter, because it is resilient to a zero length array when range checking is enabled. In that scenario, the first block of code leads to a run time range check error.

You might also be motivated to avoid such low-level trickery. I have a utility class that allows me to write:

TArray.Move<Byte>(LBytes, LArr);

The signature of the method is:

class procedure Move<T>(const Source: array of T; var Dest: array of T); overload; static;
like image 108
David Heffernan Avatar answered Sep 22 '22 02:09

David Heffernan