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

Mar*_*mke 12 delphi pointers dispose casting

假设我有一个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;
Run Code Online (Sandbox Code Playgroud)

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

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

for i := 0 to MyList.Count - 1 do
  Dispose(MyList[x]);  
Run Code Online (Sandbox Code Playgroud)

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

Rob*_*edy 13

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

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