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包含字符串,变体,接口或其他“托管”类型,则它们将被正确初始化和完成,而无需手动进行。

08-19 13:49