Как зарегистрироваться ExpectedMemoryLeak

Давайте начнем с простого кода, кодированного под D2010:

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

FastMM4 сообщает об утечке памяти снова и снова, даже с Addr(StringList) как параметр, как зарегистрировать Expected MemoryLeak и почему методы, описанные выше, не работают, спасибо заранее.

1 ответ

Решение

Вы только зарегистрировали утечку объекта списка строк. Вам также необходимо зарегистрировать утечку всех объектов, принадлежащих списку строк. В этом случае он владеет 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, Если вы хотите зарегистрировать эту утечку, вам нужно будет сделать еще несколько взломов, потому что вам снова придется полагаться на детали реализации относительно того, где хранится этот массив.

Другие вопросы по тегам