tags:

views:

498

answers:

3
+3  Q: 

How to copy array?

Hello,

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!

+3  A: 

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.

smok1
I have one question.The VirtualFree always returns false so how do I free the mem currently used with DataR? Note DataR is not local,but class var in the original code.Thank you in advance for the answer!
John
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
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.
smok1
+2  A: 

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;
Roee Adler
I did,it doesn't work.
John
+2  A: 

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;
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.
Rob Kennedy