Search code examples
delphilazarusfreepascal

Copy array with pointers


I have array

type
Ttable=array[0..7] of ^TRecord;
var
table:Ttable;

I would like to create temporary tmp table with the same values, however, the temporary change does not affect the right one.

Could you help me?


Solution

  • The issue that you have is that if you copy a table of pointers, the pointers still point to the original objects or records, and therefore any manipulation will affect the original data.

    To avoid this you need to copy the original records, not the pointers to them. You indicate (but don't actually state) that you are using records rather than objects. The difference is the disposal of the newly created objects - for records you don't need to, but for objects you do. In your case you might want to make the array permanat for future reuse.

    To illustrate I added 3 memo fields to a form. Two notes - you need to create a second set of records somehow, and the important bit is CopyTable

    unit Unit2;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
      Unit3, Vcl.StdCtrls;
    
    type
      TRecord = record
        Something : integer;
      end;
    
      TTable = array[0..7] of ^TRecord;
    
      TForm2 = class(TForm)
        Memo1: TMemo;
        Memo2: TMemo;
        Memo3: TMemo;
        procedure FormShow(Sender: TObject);
      private
        { Private declarations }
        Record0 : TRecord;
        Record1 : TRecord;
        Record2 : TRecord;
        Record3 : TRecord;
        Record4 : TRecord;
        Record5 : TRecord;
        Record6 : TRecord;
        Record7 : TRecord;
        TempRecord0 : TRecord;
        TempRecord1 : TRecord;
        TempRecord2 : TRecord;
        TempRecord3 : TRecord;
        TempRecord4 : TRecord;
        TempRecord5 : TRecord;
        TempRecord6 : TRecord;
        TempRecord7 : TRecord;
        fTempTable : TTable;
      public
        Table : TTable;
        { Public declarations }
        procedure CopyTable;
        procedure ShowTable( const ATable : TTable; const AMemo : TMemo );
      end;
    
    var
      Form2: TForm2;
    
    implementation
    
    {$R *.dfm}
    
    { TForm2 }
    
    procedure TForm2.CopyTable;
    var
      i: Integer;
    begin
      for i := 0 to 7 do
      fTempTable[i]^ := Table[ i ]^;
    end;
    
    procedure TForm2.FormShow(Sender: TObject);
    var
      i: Integer;
    begin
      // Set up tables
      Table[0] := @Record0;
      fTempTable[0] := @TempRecord0;
      Table[1] := @Record1;
      fTempTable[1] := @TempRecord1;
      Table[2] := @Record2;
      fTempTable[2] := @TempRecord2;
      Table[3] := @Record3;
      fTempTable[3] := @TempRecord3;
      Table[4] := @Record4;
      fTempTable[4] := @TempRecord4;
      Table[5] := @Record5;
      fTempTable[5] := @TempRecord5;
      Table[6] := @Record6;
      fTempTable[6] := @TempRecord6;
      Table[7] := @Record7;
      fTempTable[7] := @TempRecord7;
      for i := 0 to 7 do
      begin
        Table[i]^.Something := i;
      end;
      ShowTable( Table, Memo1 );
      CopyTable;
      fTempTable[ 5 ].Something := 73;
      ShowTable( fTempTable, Memo2 );
      ShowTable( Table, Memo3 );
    end;
    
    procedure TForm2.ShowTable(const ATable: TTable; const AMemo: TMemo);
    var
      i: Integer;
    begin
      AMemo.Clear;
      for i := 0 to 7 do
      begin
        AMemo.Lines.Add( IntToStr( ATable[i]^.Something));
      end;
    end;
    
    end.