delphi - A generic list of records that contains dynamic array -


i have generic list of records. these records contains dynamic array following

type   tmyrec=record myarr:array of integer;     name: string;     completed: boolean;   end;  var   mylist:tlist<tmyrec>;   myrec:tmyrec; 

then create list , set array length followings

mylist:=tlist<tmyrec>.create; setlength(myrec.myarr,5); myrec.myarr[0]:=8;  // demonstration myrec.name:='record 1'; myrec.completed:=true; mylist.add(myrec); 

then change data in myarr , change myrec.name , add item list

myrec.myarr[0]:=5;  // demonstration myrec.name:='record 2'; myrec.completed:=false; mylist.add(myrec); 

when myrec.myarr changes after adding first item list, myarr stored list changes. other record fields not.

my question how prevent changes in myrec.myarr reflected on array stored in list item.

do need declare multiple records.

this example can simplified so, removing reference 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. 

the output is:

 42 666 

the reason dynamic array reference type. when assign variable of dynamic array type, taking reference , not making copy.

you can resolve forcing reference unique (that have simple reference). there number of ways achieve this. instance, can call setlength on array want unique.

{$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. 

output:

 42 42 

so, in code can write this:

mylist:=tlist<tmyrec>.create;  setlength(myrec.myarr,5); myrec.myarr[0]:=8;  // demonstration myrec.name:='record 1'; myrec.completed:=true; mylist.add(myrec);  setlength(myrec.myarr,5); // <-- make array unique myrec.myarr[0]:=5;  // demonstration myrec.name:='record 2'; myrec.completed:=false; mylist.add(myrec); 

you can use variety of other ways enforce uniqueness, including finalize, assigning nil, copy, etc.

this issue covered in detail in documentation. here pertinent excerpts:

if x , y variables of same dynamic-array type, x := y points x same array y. (there no need allocate memory x before performing operation.) unlike strings , static arrays, copy-on-write not employed dynamic arrays, not automatically copied before written to. example, after code executes:

 var    a, b: array of integer;    begin      setlength(a, 1);      a[0] := 1;      b := a;      b[0] := 2;    end; 

the value of a[0] 2. (if , b static arrays, a[0] still 1.) assigning dynamic-array index (for example, myflexiblearray[2] := 7) not reallocate array. out-of-range indexes not reported @ compile time. in contrast, make independent copy of dynamic array, must use global copy function:

 var    a, b: array of integer;  begin    setlength(a, 1);    a[0] := 1;    b := copy(a);    b[0] := 2; { b[0] <> a[0] }  end; 

Comments

Popular posts from this blog

php - regexp cyrillic filename not matches -

c# - OpenXML hanging while writing elements -

sql - Select Query has unexpected multiple records (MS Access) -