2

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

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

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

4

1 回答 1

3

您只注册了字符串列表对象的泄漏。您还需要注册您正在泄漏字符串列表拥有的所有对象。在这种情况下,它拥有对象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。如果您想注册该泄漏,那么您需要做更多的黑客攻击,因为您将不得不再次依赖实现细节来确定该数组的存储位置。

于 2013-03-23T10:46:24.147 回答