我需要在Delphi中完成记录数组吗?

时间:2013-02-19 13:12:28

标签: delphi record dynamic-arrays delphi-6 finalization

在我的申请表中,我有以下记录:

TTransaction = record
  Alias: string
  Description: string
  Creation: TDateTime
  Count: Integer
end;

我在这个数组中使用此记录:

Transactions = array of TTransaction;

我在运行时保持数组加载,但在给定时间我需要清除所有数据并添加一些新数据。

仅仅使用就足够了:

SetLength(Transactions, 0); ?

或者我需要完成一些事情吗?

3 个答案:

答案 0 :(得分:15)

有三种方法可以释放与动态数组相关的内存关联a

SetLength(a, 0);
Finalize(a);
a := nil;

由您决定使用哪一个。

documentation说的是相同的,尽管方式略有不同:

  

要解除分配动态数组,请将nil指定给引用该数组的变量,或将该变量传递给Finalize;这些方法中的任何一个都会处理数组,前提是没有其他引用。动态数组在其引用计数降至零时自动释放。长度为0的动态数组的值为nil。

这将释放与数组关联的所有内存,包括任何嵌套的托管类型,例如您的记录类型所拥有的字符串,动态arrys等。

如果您需要调整阵列的大小以供将来使用,并且新数据可用,只需使用SetLength调整大小,并适当地初始化其余元素。

答案 1 :(得分:10)

将数组长度设置为零将破坏数组,这违背了“保持数组加载”的愿望。但是,它释放所有记录及其字符串的内存(对于当时引用计数为1的任何字符串)。

如果你只想释放字符串的内存,但保留记录内存分配(因为你打算在之后立即分配另一组记录,你不想浪费释放和重新分配它们内存),然后你可以只清除字符串成员,但没有单个库调用来为你做。相反,您需要编写一个循环并自己清除每个记录的字段。

for i := 0 to High(transactions) do begin
  transactions[i].alias := '';
  transactions[i].description := '';
end;

如果记录中有许多需要清除的字段,那么为数组的每个元素分配一个默认的TTransaction值可能会更方便。您可以使用Default函数,或者在旧版本的Delphi中,您可以声明已清除其所有字段的TTransaction

const
  ClearTransaction: TTransaction = (alias: ''; description: ''; creation: 0; count: 0);

for i := 0 to High(transactions) do
  transactions[i] := ClearTransaction;
  // or
  transactions[i] := Default(TTransaction);

答案 2 :(得分:0)

SetLength (transactions,0)不是个好主意。我认为最好的方法是重新初始化所有记录的成员。这样就可以保持变量的加载。

如果您不再需要变量,可以使用SetLength (transactions,0),以尽可能少地使用内存。当然,如果你在程序的某个地方再次需要它,你可以重新调整它的长度,假设你知道它。

你不需要敲定任何东西,因为它是一个记录,而不是一个类。记录没有构造函数析构函数,就像类一样。