首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GetMem x ReallocMem

GetMem x ReallocMem
EN

Stack Overflow用户
提问于 2009-02-20 15:31:42
回答 2查看 4.6K关注 0票数 5

System.GetMem和System.ReallocMem有什么区别?

Delphi2009Help为ReallocMem,是完全相同的描述GetMem。System.FreeMem和System.Dispose怎么样?

我应该对数组使用什么?

代码语言:javascript
复制
type
  PMemberDataList = ^TMemberDataList;
  TMemberDataList = array[0..MaxClassMembers -1] of PMemberData;

var
  FItems: PMemberDataList;

begin
  GetMem(FItems, Value * SizeOf(Pointer));
  FreeMem(FItems);
end;

代码语言:javascript
复制
begin
  ReallocMem(FItems, Value * SizeOf(Pointer));
  Dispose(FItems);
end;

溶液

在人们提出建议之后,我声明FItems为记录类型,而不是记录指针,TMemberDataList为动态数组,SetLength为(De)分配数组,New/Dispose为数据

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-02-20 16:09:02

GetMem总是分配内存,FreeMem总是释放/释放内存,ReallocMem可以做一个、另一个,或者两者兼而有之。事实上,如果使用得当,ReAllocMem实际上是唯一需要的内存管理API。如果以零指针开始,并调用大小大于0的ReAllocMem,则它的作用类似于GetMem。如果您使用size = 0调用ReAllocMem,那么它的作用类似于FreeMem。它真正“重新分配”内存的唯一时间是指针非零且大小大于0。

New和Dispose被设计用来处理类型化指针,或者为您设计的“旧-skool”对象模型(旧的“对象”)语法。New和Dispose还将确保对托管类型的任何类型指针都能正确地初始化该类型。例如,给定以下条件:

代码语言:javascript
复制
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将确保记录的名称和值字段被正确初始化、最后确定或清除。在上述情况下,新的和处置相当于:

代码语言:javascript
复制
GetMem(Rec, SizeOf(Rec^));
Initialize(Rec);
...
Finalize(Rec);
FreeMem(Rec);

举个例子,Gamecat是正确的,您可能最好使用动态数组,因为它们更好地由编译器管理,而且它们还带有自己的内部长度。对于您的示例,您必须单独跟踪数组中的项数,这样,无论您在哪个数组周围传递,您都必须传递当前分配的长度。通过使用动态数组,所有信息都被整齐地打包在一起。这将允许您只执行以下操作之一,而不管当前长度如何,都可以迭代数组:

代码语言:javascript
复制
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包含字符串、变体、接口或其他“托管”类型,则它们将被正确初始化和最后确定,而无需手动完成。

票数 20
EN

Stack Overflow用户

发布于 2009-02-20 15:36:09

GetMem分配一个内存块。ReallocMem重新分配内存块.

但是最好使用动态数组:

代码语言:javascript
复制
var
  FItems : array of TMemberDataList;

begin
  SetLength(FItems, Value);
end;

这更像是德尔菲的方式。

示例

你可以这样做:

代码语言:javascript
复制
type
  TMemberDataList = array[0..MaxClassMembers -1] of TMemberData;

var
  FItems: TMemberDataList;
begin
  // Don't need to allocate FItems
end;

或者:

代码语言:javascript
复制
type
  TMemberDataList = array of TMemberData;

var
  FItems: TMemberDataList;
begin
  SetLength(FItems, MaxClassMembers);
end;

类变量是指针。因此,您不必像我们对TP那样使用显式指针。您仍然可以使用指向记录或对象的指针,但是没有理由这样做。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/569995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档