Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2018-05

Copy dynamic array

13 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Torsten Bonde Christiansen

Hi List.

This i a real newbie question:

I hardly use dynamic array, so I don't know if there is a simpler method to copying a dynamic interger array than the straigh forward method:

(I need a copy to preseve the current values of OldArray, since OldArray will change values later in the program)

SetLength(NewArray, Length(OldArray));
for i := Low(OldArray) to High(OldArray) do
   NewArray[i] := OldArray[i];

Best regards,
Torsten.

Maciej Izak
to Torsten Bonde Christiansen

2018-05-14 11:46 GMT+02:00 Torsten Bonde Christiansen :

SetLength(NewArray, Length(OldArray)); for i := Low(OldArray) to High(OldArray) do NewArray[i] := OldArray[i];

you can just use :

NewArray := Copy(OldArray);

looks better ;)

Best regards, Maciej Izak
Bart
to Maciej Izak
Maciej Izak wrote
you can just use : NewArray := Copy(OldArray);

Mind you, if OldArray is an array of array, Copy() will copy the reference to the "second" array, not the actal data.

var
  a,b: array of array of TSomeType;
SetLength(a, 5, 5);
a[0,0] := VarOfTSomeType;
b := copy(a);
a[0,0] := SecondVarOfTSomeType;
writeln(b[0,0]); //prints SecondVarOfTSomeType.
You would need to do b[i] := copy(a[i]) in a loop to copy the data.

Bart

denisgolovan
to Bart

A side note:

I am still wondering why there is no something like "Clone" function to make an independent copy of string/array/... ? It's used quite often in practice (as we don't have copy-on-write working in all circumstances).

BR,
Denis

Florian Klämpfl
to denisgolovan
denisgolovan wrote
A side note: I am still wondering why there is no something like "Clone" function to make an independent copy of string/array/... ? It's used quite often in practice (as we don't have copy-on-write working in all circumstances).

There is. It is just called copy.

denisgolovan
to Florian Klämpfl

Well.

"Copy" works for arrays only.
Neither strings nor records work.
Tested in pretty old svn rev. 37656

//=================================================
program project1;
{$mode objfpc}{$H+}
type
  TRec = record
    s1:string;
    i1:integer;
  end;
var S1,S2:string;
    A1,A2:array of integer;
    R1,R2:TRec;
begin
  A1:=[1,2,3];
  A2:=Copy(A1);
  A2[0]:=10;
  writeln(A1[0]);
  writeln(A2[0]);
  S1:='123';
  S2:=Copy(S1);
  R1.s1:='123';
  R1.i1:=1;
  R2:=Copy(R1);
end.
//===========================================

BR,
Denis

Alexander Grotewohl
to denisgolovan
type
   TRec = record
     s1:string;
     i1:integer;
   end;
var
   S1,S2:string;
   R1,R2:TRec;
begin
   S1:='123';
   S2:=S1; // lol
   R1.s1:='123';
   R1.i1:=1;
   move(R1, R2, sizeof(TRec));
   writeln(R2.s1, ' ', R2.i1);
end.
denisgolovan wrote 41 lines
Well. "Copy" works for arrays only. Neither strings nor records work. Tested in pretty old svn rev. 37656 //================================================= program project1; {$mode objfpc}{$H+} type TRec = record s1:string; i1:integer; end; var S1,S2:string; A1,A2:array of integer; R1,R2:TRec; begin A1:=[1,2,3]; A2:=Copy(A1); A2[0]:=10; writeln(A1[0]); writeln(A2[0]); S1:='123'; S2:=Copy(S1); R1.s1:='123'; R1.i1:=1; R2:=Copy(R1); end. //=========================================== BR, Denis _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Alexander Grotewohl
to Alexander Grotewohl

I should probably also note that you shouldn't use move with records that have ansistrings or other dynamically allocated variables in them..

Alexander Grotewohl wrote 66 lines
type   TRec = record     s1:string;     i1:integer;   end; var   S1,S2:string;   R1,R2:TRec; begin   S1:='123';   S2:=S1; // lol   R1.s1:='123';   R1.i1:=1;   move(R1, R2, sizeof(TRec));   writeln(R2.s1, ' ', R2.i1); end. On 5/15/2018 2:39 PM, denisgolovan wrote: > Well. > > "Copy" works for arrays only. > Neither strings nor records work. > Tested in pretty old svn rev. 37656 > > //================================================= > program project1; > > {$mode objfpc}{$H+} > > type >    TRec = record >      s1:string; >      i1:integer; >    end; > > var S1,S2:string; >      A1,A2:array of integer; >      R1,R2:TRec; > begin >    A1:=[1,2,3]; >    A2:=Copy(A1); >    A2[0]:=10; >    writeln(A1[0]); >    writeln(A2[0]); > >    S1:='123'; >    S2:=Copy(S1); > >    R1.s1:='123'; >    R1.i1:=1; >    R2:=Copy(R1); > end. > //=========================================== > > BR, > Denis > _______________________________________________ > fpc-pascal maillist  -  > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist  -  http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Michael Van Canneyt
to denisgolovan
denisgolovan wrote
Yes. That's exactly why I gave that example. Your method with Move will trigger segfault eventually, so the compiler support is required to handle it properly.

But compiler support for copying records exists.

What's wrong with simply doing

  R2:=R1;

in the given examples ?

Michael.

denisgolovan
to Michael Van Canneyt

Doing the same conceptual thing using different syntax does not seem right as generics, macros and other nice stuff become clumsy and too verbose.

See

//========================================================
program project1;
{$mode objfpc}
type
   TRec= record
      A:array of integer;
      S:string;
   end;
var R1,R2:TRec;
begin
   SetLength(R1.A, 3);
   R1.A[0]:=1;
   R1.A[1]:=2;
   R1.A[2]:=3;
   R1.S:='123';
   R2:=R1; // shallow copying  full clone
   R2.A[0]:=10;
   R2.S[1]:='S';
   // does not work as expected (no copy-on-write/cloning)
   writeln(R1.A[0]); // prints 10
   writeln(R2.A[0]); // prints 10
   // works fine
   writeln(R1.S[1]); // prints 1
   writeln(R2.S[1]); // prints S
end.
//========================================================

BR,
Denis

Alexander Grotewohl
to denisgolovan

What would the expected behavior be for pointers inside records? What if the record is actually a linked list? Or includes classes and objects? Do we run the constructor or no? If the record has file handles do we attempt to recreate their state? (perhaps running assign again, and crossing our fingers the file hasn't been deleted - which at least on Linux is definitely possible)

denisgolovan wrote 41 lines
Doing the same conceptual thing using different syntax does not seem right as generics, macros and other nice stuff become clumsy and too verbose. See //======================================================== program project1; {$mode objfpc} type TRec= record A:array of integer; S:string; end; var R1,R2:TRec; begin SetLength(R1.A, 3); R1.A[0]:=1; R1.A[1]:=2; R1.A[2]:=3; R1.S:='123'; R2:=R1; // shallow copying full clone R2.A[0]:=10; R2.S[1]:='S'; // does not work as expected (no copy-on-write/cloning) writeln(R1.A[0]); // prints 10 writeln(R2.A[0]); // prints 10 // works fine writeln(R1.S[1]); // prints 1 writeln(R2.S[1]); // prints S end. //======================================================== BR, Denis _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
denisgolovan
to Alexander Grotewohl
Show quoted text 6 lines
What would the expected behavior be for pointers inside records? What if the record is actually a linked list? Or includes classes and objects? Do we run the constructor or no? If the record has file handles do we attempt to recreate their state? (perhaps running assign again, and crossing our fingers the file hasn't been deleted - which at least on Linux is definitely possible)

Well.
The answer is simple - value types (scalars, strings, records, variants, arrays of mentioned) are good functional citizens. Cloning is well defined for them as compound value is also value.

Should someone wants for add complexity (read OOP/pointers/classes and other crap) - use http://wiki.freepascal.org/management_operators#Copy at your own risk.

Regards, Denis Golovan