System.GetMem和System.ReallocMem有什么区别?
Delphi 2009 ReallocMem帮助与GetMem的描述完全相同。
System.FreeMem和System.Dispose怎么样
我应该对数组使用什么?
type
PMemberDataList = ^TMemberDataList;
TMemberDataList = array[0..MaxClassMembers -1] of PMemberData;
var
FItems: PMemberDataList;
begin
GetMem(FItems, Value * SizeOf(Pointer));
FreeMem(FItems);
end;
要么
begin
ReallocMem(FItems, Value * SizeOf(Pointer));
Dispose(FItems);
end;
解
根据人们的建议,我将FItems声明为记录类型,而不是指向记录的指针,将TMemberDataList声明为动态数组,将SetLength设置为(de)alloc数组,将New / Dispose设置为数据
type
PMemberDataList = ^TMemberDataList;
TMemberDataList = array of PMemberData;
var
Items: TMemberDataList;
Item: PMemberData;
// Add
begin
Setlength(Items, 1);
New(Item);
Items[0]:= Item
end;
// Remove
begin
Dispose(Items[0]);
Setlength(Items, 0);
end;
最佳答案
GetMem总是分配内存,FreeMem总是释放/释放内存,ReallocMem可以执行一个或另一个。实际上,如果使用得当,ReAllocMem实际上是唯一需要的内存管理API。如果从nil指针开始,并调用大小大于0的ReAllocMem,则其行为类似于GetMem。如果您以大小= 0调用ReAllocMem,则其行为类似于FreeMem。它唯一真正“重新分配”内存的时间是指针是否为非零且大小> 0。
New和Dispose设计用于与类型化指针配合使用,或者针对您的“老派”人士使用较旧的Turbo Pascal对象模型(旧的“ object”语法)。New和Dispose还可以确保任何引用了a托管类型将正确初始化该类型,例如给出以下内容:
type
PMyRec = ^TMyRec;
TMyRec = record
Name: string;
Value: Variant;
end;
var
Rec: PMyRec;
begin
New(Rec);
try
Rec.Name := 'TestValue';
Rec.Value := 100;
...
finally
Dispose(Rec);
end;
end;
“新建”和“处置”将确保记录的“名称”和“值”字段已正确初始化,完成或清理。在上述情况下,New和Dispose等效于:
GetMem(Rec, SizeOf(Rec^));
Initialize(Rec);
...
Finalize(Rec);
FreeMem(Rec);
对于您给出的示例,Gamecat是正确的,使用动态数组可能会更好,因为它们可以由编译器更好地管理,并且它们也具有自己的固有长度。对于您的示例,您将必须分别跟踪数组中的项目数,这样无论您在数组中传递的位置如何,都还必须传递当前分配的长度。通过使用动态数组,所有信息都可以整齐地打包在一起。这将允许您通过简单地执行以下操作之一来遍历数组,而不管当前的长度如何:
var
Member: TMemberData;
Items: array of TMemberData;
...
begin
SetLength(Items, Value);
for Member in Items do // iterate over each element in the array
...
for Low(Items) to High(Items) do // same as above only using std functions
...
end;
最后,您可能想使用动态数组的另一个原因是,如果TMemberData包含字符串,变体,接口或其他“托管”类型,则它们将被正确初始化和完成,而无需手动进行。