让我们从D2010下编码的简单代码开始:
var
StringList: TStringList;
begin
ReportMemoryLeaksOnShutdown := True;
StringList := TStringList.Create;
StringList.LoadFromFile('c:\fateh.txt');
RegisterExpectedMemoryLeak(StringList);
即使Addr(StringList)
作为参数,FastMM4也会一次又一次地报告内存泄漏
所以如何注册预期的MemoryLeak以及为什么上面的方法不起作用
谢谢你提前。
答案 0 :(得分:2)
您只注册了字符串列表对象的泄漏。您还需要注册您正在泄漏字符串列表所拥有的所有对象。在这种情况下,它拥有StringList.Count
个string
个对象的实例。内存管理器不知道这些字符串是字符串列表对象所拥有的,因此也会泄露。
说起来容易做起来难。因为您需要找到表示字符串的内存块的开头。这是与字符串的第一个字符的固定偏移量,偏移量取决于您使用的Delphi版本。
在Unicode Delphi中,在32位代码中,偏移量为12个字节。因此,以下内容将注册泄露的字符串:
for i := 0 to StringList.Count-1 do
if StringList[i]<>'' then
RegisterExpectedMemoryLeak(PByte(StringList[i])-12);
即使你这样做,你仍然会得到两个报告的内存泄漏。其中至少有一个是由字符串列表TStringList.FList
所拥有的动态数组解释的。如果你想注册那个泄漏,那么你需要做一些更多的黑客攻击,因为你必须依赖实现细节来确定存储该数组的位置。