1

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;

これは質問には関係ないはずです。これが私が文字列を漏らしている理由です:

アプリケーションの存続期間中、特定のデータを保存するためにキャッシュメカニズムを使用しています。これらのオブジェクトを解放するつもりはありません。アプリケーションの存続期間中はオブジェクトが必要であり、適切なファイナライズを実行するのは、アプリケーションのシャットダウン時の時間を無駄にするだけだからです。これらのオブジェクトにはいくつかの文字列フィールドが含まれているため、明らかにこれらの文字列は「リーク」されます。

4

1 に答える 1

2

The closest I can think of would be:

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;

The re-declaration of StrRec is copied from Delphi XE's getmem.inc (FastMM4) - I only added the {$ifdef CONDITIONALEXPRESSIONS}. I think it should be backwards-compatible with older versions of Delphi, too.

于 2011-05-11T12:16:10.920 に答える