Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我需要在Delphi中完成记录数组吗?_Delphi_Record_Dynamic Arrays_Delphi 6_Finalization - Fatal编程技术网

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

我需要在Delphi中完成记录数组吗?,delphi,record,dynamic-arrays,delphi-6,finalization,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);

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

TTransaction = record
  Alias: string
  Description: string
  Creation: TDateTime
  Count: Integer
end;
我在这个数组中使用这个记录:

Transactions = array of TTransaction;
我将在运行时加载数组,但在给定时间,我需要清除所有数据并添加一些新数据

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

SetLength(Transactions, 0); ?
或者我需要完成一些事情吗?

设置长度(事务,0)
不是一个好主意。我认为最好的方法是重新初始化所有记录的成员。这样,就可以保持变量的加载状态

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


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

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

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

for i := 0 to High(transactions) do begin
  transactions[i].alias := '';
  transactions[i].description := '';
end;
如果记录中有许多字段需要清除,那么为数组的每个元素指定默认值
t transaction
可能更方便。您可以使用
Default
函数,或者在旧版本的Delphi中,您可以声明一个
t已清除所有字段的Transaction

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

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

有三种方法可以解除分配与动态数组关联的内存,
a

SetLength(a, 0);
Finalize(a);
a := nil;
用哪一个取决于你

这句话也是这么说的,尽管有点绕圈子:

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

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


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

不过
Finalize
是否确实更改了
a
的值?我一直认为它不会-它释放内存,同时将动态数组的原始地址存储在
a
中,在预期后续调用
Free
Initialize
@Rob时,这三个选项都是等效的。对于托管类型,Finalize必须将引用设置为nil。它别无选择。考虑一个类型的动态数组的局部变量。@ DavidHeffernan在数组的最高边界为10的情况下,最好使用:1 -设置为零,并重新创建所有。2-将使用的索引与下一个值关联??可能无关紧要。不管你喜欢哪个。我想这是最好的。。。因为是用户决定何时重新加载所有数据,所以我知道记录类型是一个结构,在我的原始类型中,这就是我问的原因。谢谢你的回答。现在的问题涉及到了第二部分的主题,答案是:@DavidHeffernan,我读过这个主题,这就是为什么我问关于定稿的问题。我被这么多的答案弄糊涂了,那个家伙说finalize+fillchar…在其他答案中有一种荒谬的噪音。愚蠢的优化,毫无意义的漫无边际。这里的公认答案是你需要阅读的,即使我自己这么说。你不需要显式清空字段,因为你有
Finalize
来自动完成。“你可以重新调整它的长度”-但请记住,这样你可能会复制所有旧项目及其所有静态内容和动态内容(字符串,dyn数组)的引用计数可能会增加/减少。这就是为什么在某些情况下,我会在更改长度之前使用完整数组释放。“你不需要完成任何事情,因为它是一个记录,而不是一个类”-只有当所有记录字段都是简单类型(不是字符串/dyn数组/接口)时才是如此。