Alex Hide
Alex Hide

Reputation: 545

Delphi. Multidimensional array as argument

I have multidimensional array:
TBMArray = TArray<array of byte>;
And recursive function
function goForSolve(bData: TBMArray; const iSize: integer): TBMArray;

At this function i have
tempData: TBMArray;
I need to change tempData without changing the value of bData. But when i change tempData, bData also changes. I tried to copy bData to tempData by function

procedure copyData(Source: TBMArray; var Dest: TBMArray);  
var  
  iCurEl, iLen: integer;  
begin  
  iLen := length(Source);  
  setLength(Dest, iLen);  
  setLength(Dest[0], 1);  
  for iCurEl := 1 to iLen - 1 do  
    setLength(Dest[iCurEl], iCurEl + 1);  
  for iCurEl := Low(Source) to High(Source) do  
    Dest[iCurEl] := Source[iCurEl];  
end;  

But result is the same as

tempData := bData;

It seems like function copy pointers instead of values.

Upvotes: 2

Views: 1514

Answers (1)

David Heffernan
David Heffernan

Reputation: 613511

A dynamic array is a reference type. Behind the scenes they are implemented as pointers to the data structure. When you assign a dynamic array variable you are simply taking another reference to the existing dynamic array object. So, that explains the behaviour you observe.

There is a function that can be used to make a copy of a dynamic array, the aptly named Copy. So you could write:

Dest := Copy(Source);

This would make a copy of the outer array, but not the inner arrays. So instead you will need to iterate over the outer arrays yourself, and call Copy to make new copies of the inner arrays. Perhaps like this:

type
  TBMArray = TArray<TArray<Byte>>;

function CopyBMArray(const src: TBMArray): TBMArray;
var
  i: Integer;
begin
  SetLength(Result, Length(src));
  for i := 0 to high(Result) do begin
    Result[i] := Copy(src[i]);
  end;
end;

Note that I have tweaked the definition of TBMArray. I urge you to do the same since it will greatly ease your development. Generic types have much more relaxed type compatibility rules and using TArray<T> wherever possible will lead to much more composable code.

Upvotes: 6

Related Questions