A shared list of records containing a dynamic array

I have a general list of entries. these records contain a dynamic array, for example, the following

Type
  TMyRec=record
MyArr:Array of Integer;
    Name: string;
    Completed: Boolean;
  end;

var
  MyList:TList<TMyRec>;
  MyRec:TMyRec;

then I create a list and set the length of the array as shown below.

MyList:=TList<TMyRec>.Create;
SetLength(MyRec.MyArr,5);
MyRec.MyArr[0]:=8;  // just for demonstration
MyRec.Name:='Record 1';
MyRec.Completed:=true;
MyList.Add(MyRec);

then I change the data in MyArrand also change MyRec.Nameand add another item to the list

MyRec.MyArr[0]:=5;  // just for demonstration
MyRec.Name:='Record 2';
MyRec.Completed:=false;
MyList.Add(MyRec);

when MyRec.MyArrchanges after adding the first item to the list MyArr, which is saved in the list also changes. however, other record fields do not work.

My question is how to prevent changes from changing in MyRec.MyArran array that is already stored in the list item.

I need to declare several entries.

+4
3

, generics:

{$APPTYPE CONSOLE}

var
  x, y: array of Integer;

begin
  SetLength(x, 1);
  x[0] := 42;
  y := x;
  Writeln(x[0]);
  y[0] := 666;
  Writeln(x[0]);
end.

:

42
666

, . , .

, ( ). . , SetLength , .

{$APPTYPE CONSOLE}

var
  x, y: array of Integer;

begin
  SetLength(x, 1);
  x[0] := 42;
  y := x;
  SetLength(y, Length(y));
  Writeln(x[0]);
  y[0] := 666;
  Writeln(x[0]);
end.

:

42
42

, :

MyList:=TList<TMyRec>.Create;

SetLength(MyRec.MyArr,5);
MyRec.MyArr[0]:=8;  // just for demonstration
MyRec.Name:='Record 1';
MyRec.Completed:=true;
MyList.Add(MyRec);

SetLength(MyRec.MyArr,5); // <-- make the array unique
MyRec.MyArr[0]:=5;  // just for demonstration
MyRec.Name:='Record 2';
MyRec.Completed:=false;
MyList.Add(MyRec);

, Finalize, nil, Copy ..

. :

X Y , X: = Y X , Y. ( X .) , copy-on-write , . , :

 var
   A, B: array of Integer;
   begin
     SetLength(A, 1);
     A[0] := 1;
     B := A;
     B[0] := 2;
   end;

A [0] 2. ( A B , A [0] 1.) (, MyFlexibleArray [2]: = 7) . . , , :

 var
   A, B: array of Integer;
 begin
   SetLength(A, 1);
   A[0] := 1;
   B := Copy(A);
   B[0] := 2; { B[0] <> A[0] }
 end;
+4

...

, , . . SetLength List.Add, , - , .

  TMyRec=record
    MyArr: TArray< double >; // making it 1D for simplicity
    Name: string;
    Completed: Boolean;
  end;


SetLength(MyRec.MyArr,5);
MyRec.MyArr[0]:=8;  // just for demonstration
MyRec.Name:='Record 1';
MyRec.Completed:=true;
MyList.Add(MyRec);
MyRec.MyArr := nil; // breaking the parasite link immediately!

... , , MyRec .

, , , ? , Delphi : http://docwiki.embarcadero.com/Libraries/XE5/en/System.Finalize, .

SetLength(MyRec.MyArr,5);
MyRec.MyArr[0]:=8;  // just for demonstration
MyRec.Name:='Record 1';
MyRec.Completed:=true;
MyList.Add(MyRec);
Finalyze(MyRec); // breaking all the parasite links immediately!

, . , Delphi Finalize .

Procedure AddRec( const Name: string; const Compl: boolean; const Data: array of double);
var i: integer; MyRec: TMyRec;
begin
  SetLength(MyRec.MyArr, Length( Data ) );
  for i := 0 to Length(Data) - 1 do
    MyRec.MyArr[i] := Data [i];  

  MyRec.Name := Name;

  MyRec.Completed := Compl;
  MyList.Add(MyRec);
end;

MyList:=TMyList<TMyRec>.create;

AddRec( 'Record 1', True , [ 8 ]);
AddRec( 'Record 2', False, [ 5 ]);
...

MyRec , AddRec, , -, .

+4

, ,

MyList:=TList<TMyRec>.Create;
SetLength(MyRec.MyArr,5);
MyRec.MyArr[0]:=8;  // just for demonstration
MyRec.Name:='Record 1';
MyRec.Completed:=true;
MyList.Add(MyRec);

MyRec := TMyRec.Create();
SetLength(MyRec.MyArr,5);

MyRec.MyArr[0]:=5;  // just for demonstration
MyRec.Name:='Record 2';
MyRec.Completed:=false;
MyList.Add(MyRec);
-1

Source: https://habr.com/ru/post/1524725/


All Articles