17

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

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

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

Transactions = array of TTransaction;

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

仅使用以下内容是否足够:

SetLength(Transactions, 0); ?

还是我需要完成一些事情?

4

3 回答 3

17

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

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

使用哪一个取决于您。

文档也说了同样的话,尽管方式有点绕:

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

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

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

于 2013-02-19T13:27:08.100 回答
11

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

如果您只想为字符串释放内存,但保留分配的记录内存(因为您计划在之后立即分配另一组记录,并且您不希望浪费释放和重新分配相同的内存),那么您可以只清除字符串成员,但没有单个库调用可以为您执行此操作。相反,您需要自己编写一个循环并清除每条记录的字段。

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

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

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

for i := 0 to High(transactions) do
  transactions[i] := ClearTransaction;
  // or
  transactions[i] := Default(TTransaction);
于 2013-02-19T13:23:49.700 回答
0

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

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

你不需要完成任何事情,因为它是一个记录,而不是一个类。记录没有构造函数析构函数,就像类一样。

于 2013-02-19T13:21:40.357 回答