Используя FastMM4, как зарегистрировать пропущенную строку? - PullRequest
1 голос
/ 11 мая 2011

С FastMM4 можно легко зарегистрировать пропущенный указатель, но не пропущенную строку.Очевидно, оператор @, примененный к строке, на самом деле не дает нам всю строку, равно как и PChar(string);Что я могу использовать, чтобы красиво зарегистрировать пропущенную строку?

Пока я обнаружил, что это работает:

FastMM4.RegisterExpectedMemoryLeak(Pointer(NativeInt(PChar(StringVariable))-12));

Но оно зависит от магического числа 12, и это зависит от версии,и код действительно не выражает то, что происходит.Я надеюсь, что где-то есть функция RTL, которая берет строку и возвращает указатель на «основание» строки, или какой-то FastMM4 метод, который я пропустил.

Я могу упаковать этот уродливый зверь выражения впроцедура, подобная этой, но я все еще нахожу ее хакерской:

procedure RegisterExpectedStringLeak(const s:string);
begin
  {$IFDEF VER210}
  FastMM4.RegisterExpectedMemoryLeak(Pointer(NativeInt(PChar(s))-12));
  {$ELSE}
  {$MESSAGE Fatal 'This only works on Delphi 2010'}
  {$ENDIF}
end;

Это не имеет отношения к вопросу.Вот почему я пропускаю строки:

Я использую механизм кэширования для хранения определенных фрагментов данных в течение всего жизненного цикла приложения.Я не собираюсь освобождать эти объекты, потому что они нужны мне на весь срок службы приложения , и для правильной финализации требуется только время ожидания при завершении работы приложения.Эти объекты содержат несколько строковых полей, поэтому очевидно, что эти строки «просочились».

1 Ответ

2 голосов
/ 11 мая 2011

Самое близкое, что я могу придумать, будет:

function RegisterExpectedStringLeak(const S: string): Boolean;
  type
    {Have to redeclare StrRec here, because it is not in the interface section of system.pas}
    PStrRec = ^StrRec;
    StrRec = packed record
      {$ifdef CONDITIONALEXPRESSIONS}
      {$if RTLVersion >= 20}
      codePage: Word;
      elemSize: Word;
      {$ifend}
      {$endif}
      refCnt: Longint;
      length: Longint;
    end;
begin
  Result := RegisterExpectedMemoryLeak(Pointer(NativeInt(PChar(S)) - SizeOf(StrRec)));
end;

Повторное объявление StrRec скопировано из Delphi XE getmem.inc (FastMM4) - я добавил только {$ifdef CONDITIONALEXPRESSIONS}.Я думаю, что он должен быть обратно совместим с более старыми версиями Delphi.

...