Search code examples
arraysdelphirecorddelphi-10.2-tokyo

Dynamic Array of Records fails to expand


I have created a dynamic array of records which is expanded using this actionexecute method:

procedure TForm1.AddTeamActionExecute(Sender: TObject);
Var
  c : integer;
begin
  c := length(PrjRecArray);
  PrjRecArray[c].tmpLoadPrjRec (true, 'Team', 'Big Building', '123 Main Street' ,'',
    'Somewhere', 'Ohio','43210', '555-1234', 'Bob', 'Big Cheese', '555-0123', 'bob@gmail.com');

  PrjSg.Cells[0,PrjSg.RowCount-1] := (PrjRecArray[c].Team);
  PrjSg.Cells[1,PrjSg.rowcount-1] := (PrjRecArray[c].Name);
  PrjSg.Cells[2,PrjSg.rowcount-1] := (PrjRecArray[c].addr1);
  PrjSg.Cells[3,PrjSg.rowcount-1] := (PrjRecArray[c].addr2);
  PrjSg.Cells[4,PrjSg.rowcount-1] := (PrjRecArray[c].city);
  PrjSg.Cells[5,PrjSg.rowcount-1] := (PrjRecArray[c].state);
  PrjSg.Cells[6,PrjSg.rowcount-1] := (PrjRecArray[c].zip);
  PrjSg.Cells[7,PrjSg.rowcount-1] := (PrjRecArray[c].phone);
  PrjSg.Cells[8,PrjSg.rowcount-1] := (PrjRecArray[c].contact);
  PrjSg.Cells[9,PrjSg.rowcount-1] := (PrjRecArray[c].title);
  PrjSg.Cells[10,PrjSg.rowcount-1] := (PrjRecArray[c].conPhone);
  PrjSg.Cells[11,PrjSg.rowcount-1] := (PrjRecArray[c].email);
  PrjSg.RowCount := PrjSg.RowCount + 1;
  Revised(true);
  showmessage ('PrSG Rows = ' + inttostr (PrjSg.RowCount));
  c := c + 1;
  SetLength (PrjRecArray, c);
  showmessage ('PrjRecArray Rows = ' + inttostr (length(PrjRecArray)));

end;

The array is called PrjRecArray declared in the unit ( PrjRecArray : Array of TPrjRec;) and is not otherwise initialized. PrjSg is a tstringgrid contained in the form and is used to display the records.

As I add more records using the AddTeamActionExecute the stringgrid continues to increase in size correctly. However, while the PrjRecordArray expands to four records correctly, the program apparently fails on the fifth iteration at the set length line. Execution hangs and never displays the second showmessage box.

Am I missing some step for using dynamic arrays properly?


Solution

  • You access off the end of the array. Instead of

    c := length(PrjRecArray);
    

    write

    c := length(PrjRecArray) - 1;
    

    or

    c := high(PrjRecArray);
    

    Remember that dynamic arrays are zero based.

    If you enabled range checking in the compiler options then you will encounter a runtime time error for any out of bounds array access which greatly helps debugging.

    The call to SetLength would also need to be corrected. For instance

    SetLength (PrjRecArray, length(PrjRecArray) + 1);
    

    Rather than a dynamic array, using TList<T> might lead to simpler code to read and write. You can let TList<T> take care of the details of resizing its internal dynamic array.

    My only other comment is that I wonder where the array is actually populated. You extend the length, but I don't obviously see where you assign any values.