Ivan Prodanov
Ivan Prodanov

Reputation: 35522

How to copy array?

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!

Upvotes: 11

Views: 24166

Answers (4)

Alexander
Alexander

Reputation: 173

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.

Upvotes: 1

smok1
smok1

Reputation: 2950

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.

Upvotes: 8

test
test

Reputation:

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;

Upvotes: 9

Roee Adler
Roee Adler

Reputation: 33990

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;

Upvotes: 2

Related Questions