假设我有一个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]);
如果有人解释我该怎么做以及为什么,我将不胜感激。非常感谢。
答案 0 :(得分:13)
是的,必须转换为正确的指针类型。没有它,RTL不知道记录有一个字符串成员,所以它不会处理字符串。它将直接跳过释放记录自己的内存,字符串的内容将泄漏。它知道为记录释放多少内存,FreeMem
知道从GetMem
调用中释放多少内容。内存管理器知道每个分配的内存量。 (有各种方法可以跟踪它。)
Dispose
是一个“编译魔术”功能。当编译器看到您调用它时,它会为与指针类型对应的TTypeInfo
记录添加隐藏的第二个参数。这样,RTL的Dispose
函数知道如何处理它接收的指针。