为什么在调用Dispose之前必须转换为特定的指针类型?

时间:2011-10-27 13:48:43

标签: delphi pointers casting dispose

假设我有一个TList类的实例(BDS 2006,所以这是一个指针类型列表)。我放入列表的每个指针都引用New()函数分配的内存。因此,当我想清除列表时,我必须遍历它并处理每个项目,对吧?但如何正确地做到这一点?我是否必须将每个配置的项目转换为它的实际类型?

type
  TMyRec = record
    Field1: string;
    Field2: integer;
  end;
  PMyRec = ^TMyRec;

  ...

  var
    MyList: TList;
    MyRecPointer: PMyRec;
  begin
    ...
    New(MyRecPointer);
    ...
    MyList.Add(MyRecPointer);
    ...

    for i := 0 to MyList.Count - 1 do
      Dispose(PMyRec(MyList[x]));        

    MyList.Clear();
  end;

请查看最后的for循环。我将每个项目投射到PMyRec以处置内存。这有必要吗?我知道Dispose()函数有一个Pointer参数,所以在这种情况下,cast似乎很愚蠢,但我仍然不确定。因为Dispose()函数如何知道在获得一般指针类型时要处理多少内存?

这是第二种方法(没有类型转换):

for i := 0 to MyList.Count - 1 do
  Dispose(MyList[x]);  

如果有人解释我该怎么做以及为什么,我将不胜感激。非常感谢。

1 个答案:

答案 0 :(得分:13)

是的,必须转换为正确的指针类型。没有它,RTL不知道记录有一个字符串成员,所以它不会处理字符串。它将直接跳过释放记录自己的内存,字符串的内容将泄漏。它知道为记录释放多少内存,FreeMem知道从GetMem调用中释放多少内容。内存管理器知道每个分配的内存量。 (有各种方法可以跟踪它。)

Dispose是一个“编译魔术”功能。当编译器看到您调用它时,它会为与指针类型对应的TTypeInfo记录添加隐藏的第二个参数。这样,RTL的Dispose函数知道如何处理它接收的指针。