2017-07-15 20 views
0

我已创建的记录的动态阵列,其使用此actionexecute方法扩增:记录的动态数组未能扩大

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

    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; 

阵列被称为PrjRecArray在单元中声明(PrjRecArray : Array of TPrjRec;)并且也未初始化。 PrjSg是表单中包含的tstringgrid,用于显示记录。

当我使用AddTeamActionExecute添加更多记录时,stringgrid会继续正确增加大小。但是,虽然PrjRecordArray正确扩展为四条记录,但程序显然在设定长度线的第五次迭代中失败。执行挂起并且从不显示第二个showmessage框。

我错过了正确使用动态数组的一些步骤吗?

回答

5

您可以访问数组的末尾。取而代之的

c := length(PrjRecArray); 

c := length(PrjRecArray) - 1; 

c := high(PrjRecArray); 

记住,动态数组是从零开始的。

如果您在编译器选项中启用了范围检查,那么您将遇到任何超出范围数组访问的运行时错误,这极大地帮助调试。

致电SetLength也需要更正。例如

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

,而不是一个动态数组,使用TList<T>可能导致简单的代码来读取和写入。您可以让TList<T>负责调整其内部动态数组的大小。

我唯一的其他评论是,我想知道数组实际上在哪里填充。你延长了这个长度,但我不明显看到你赋值的地方。

4

Length给出该阵列的当前长度。但动态数组从索引0开始,并且它们以 - 在这种情况下为 - High(PrjRecArray)结束。您应该访问PrjRecArray[c - 1],而不是PrjRecArray[c]

另外,使用

c := High(PrjRecArray); 

然后你可以使用

PrjSg.Cells[0, PrjSg.RowCount - 1] := PrjRecArray[c].Team; 
// etc... 

在你的代码,如果你已经拥有的长度c,然后重新设置长度相同c,你确实不是扩大,你设置它已经有了相同的长度。使用

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

或者,在你的代码(假设c是长度):

SetLength(PrjRecArray, c + 1); // previous length + 1 

FWIW,如果你这样做的时候,你可能要考虑在更大incrermenting大小块(例如SetLength(PrjRecArray, c + c shr 1);SetLength(PrjRecArray, c + c div 2);,它们是相同的),并跟踪数组的实际使用的元素。这可以避免堆碎片,这可能会让你很容易地耗尽内存。

更多关于在我的blog article关于扩展数组。

+2

“shr”的使用有点不透明 –

+0

@DavidHeffernan:我编辑了这个部分。