我需要在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数组/接口)时才是如此。