How to copy array?

22,415

Solution 1

Why not use FOR?

SetLength(DataR,Length(input));
for i:=Low(input) to High(input) do
  DataR[i]:=input[i];

BTW: if you want to have arrays passing as parameter, you should declare them as a type, eg:

type
  TMyArray = array of byte;

and use TMyArray as parameters type.

Edit: I was notified about i lower value. In my original post it was for i:=0, but i:=Low(input) is safer and more pure.

Solution 2

try this

type
  TByteDynArray = array of Byte;

function CopyData(const Input:array of Byte):TByteDynArray;
begin
  SetLength(Result, Length(Input));
  Move(input[0], Result[0], Length(Input));
end;

Solution 3

Try:

class procedure TCelebrity.BeginRead(var input:Array of byte);
var DataR:Array of byte;
begin
  VirtualFree(@DataRead,High(DataRead),MEM_RELEASE);
  SetLength(DataR,Length(input));
  Move(input[0],DataR,Length(input));
end;

Solution 4

Move procedure will not move a section of memory. It copies Count bytes. Hereby you will get two different identical arrays: Input and DataR.

procedure CopyData(const Input: Array of Byte);
var 
    DataR: Array of Byte;
begin
    SetLength(DataR, Length(Input));
    Move(Input[0], DataR[0], SizeOf(Byte)*Length(Input));
end;

P.s. with static arrays you can use SizeOf(Input) instead of SizeOf(Byte)*Length(Input). Instead of Byte could be other data type.

Share:
22,415
P. Duw
Author by

P. Duw

Updated on November 21, 2020

Comments

  • P. Duw
    P. Duw over 3 years

    I have such a basic problem in Delphi,I can't solve it.

    My Code:

    Note:DataR is local in the methods below,but usually it's a class var.Just for the concept it's local.

    class procedure TCelebrity.BeginRead(var input:Array of byte);
    var DataR:Array of byte;
    begin
      VirtualFree(@DataRead,High(DataRead),MEM_RELEASE);
      SetLength(DataR,Length(input));
      Move(input,DataR,Length(input));
    end;
    

    This compiles,but after Move() is executed DataR = nil.

    Second try:

    class procedure TCelebrity.BeginRead(var input:Array of byte);
    var DataR:Array of byte;
    begin
      VirtualFree(@DataRead,High(DataRead),MEM_RELEASE);
      SetLength(DataR,Length(input));
      DataR := Copy(input,0,Length(input));
    end;
    

    This doesn't compile at all.Error at the third line(DataR := Copy(input....) saying "Incompatible types".

    Where's the problem? They are all Array of byte!

  • smok1
    smok1 almost 15 years
    No, you do not have free simple arrays. Such arrays are freed automatically (for example when your class is being destroyed). Note: if you have an array of references to objects, you have to free those objects manually, because only array will be freed by Delphi.
  • smok1
    smok1 almost 15 years
    Also note, that SetLenght reallocates the whole array, so avoid intensive usage of this procedure. When you make the array longer with SetLength, the current content remains intact, however, when you make it shorter, some of the content will be lost.
  • Rob Kennedy
    Rob Kennedy almost 15 years
    A correct answer. but to make it a good answer, you should explain why your changes are significant. Otherwise, it's just a magical incantation.
  • Richard A
    Richard A about 11 years
    Correct me if I'm wrong, but it might be worth noting that this only works as written for array of Byte. If the array was anything different, say array of Integer, then you'd need Move(input[0], Result[0], Length(Input) * SizeOf(Integer)). Just saying.
  • Richard A
    Richard A about 11 years
    In answer to 'Why not use FOR?'. My only reason would be if there was a real performance problem. If you were doing this a serious number of times, then Move would be faster, I reckon.
  • TmTron
    TmTron almost 11 years
    why not use SizeOf(Input[0]) instead of a hardcoded data-type?
  • dns
    dns over 10 years
    use Move() it's similar to memcpy()/memmove() in C. Never use FOR to copy array
  • dns
    dns over 10 years
    @Rob Kennedy: Move() in delphi is similar to memcpy()/memmove() in C
  • Rob Kennedy
    Rob Kennedy over 10 years
    I know that, @Dns. So what?
  • JensG
    JensG over 5 years
    The VirtualFree() call seems a bit superfluous.