如何RegisterExpectedMemoryLeak

时间:2013-03-23 10:32:42

标签: delphi delphi-2010 fastmm

让我们从D2010下编码的简单代码开始:

var
  StringList: TStringList;
begin
  ReportMemoryLeaksOnShutdown := True;
  StringList := TStringList.Create;
  StringList.LoadFromFile('c:\fateh.txt');
  RegisterExpectedMemoryLeak(StringList);

即使Addr(StringList)作为参数,FastMM4也会一次又一次地报告内存泄漏 所以如何注册预期的MemoryLeak以及为什么上面的方法不起作用 谢谢你提前。

1 个答案:

答案 0 :(得分:2)

您只注册了字符串列表对象的泄漏。您还需要注册您正在泄漏字符串列表所拥有的所有对象。在这种情况下,它拥有StringList.Countstring个对象的实例。内存管理器不知道这些字符串是字符串列表对象所拥有的,因此也会泄露。

说起来容易做起来难。因为您需要找到表示字符串的内存块的开头。这是与字符串的第一个字符的固定偏移量,偏移量取决于您使用的Delphi版本。

在Unicode Delphi中,在32位代码中,偏移量为12个字节。因此,以下内容将注册泄露的字符串:

for i := 0 to StringList.Count-1 do 
  if StringList[i]<>'' then
    RegisterExpectedMemoryLeak(PByte(StringList[i])-12);

即使你这样做,你仍然会得到两个报告的内存泄漏。其中至少有一个是由字符串列表TStringList.FList所拥有的动态数组解释的。如果你想注册那个泄漏,那么你需要做一些更多的黑客攻击,因为你必须依赖实现细节来确定存储该数组的位置。