c++ builder / memory leak > FastMM試用


動作確認
C++ Builder XE4

FastMMというメモリリークチェックツールを使ってみた。
他にはEurekalogというよさそうなツールがあるという情報があったが、本家のサイトはずっとサイトメンテナンス状態となっている (2016年4月16日現在)。
(追記 2016/07/15) https://www.eurekalog.com/ に接続できるようになっていた。

メモリリークコード

ボタン押下時にメモリリークするコード。

Unit1.cpp
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TStringList *lst = new TStringList();

    // without delete lst;
}
//---------------------------------------------------------------------------

FastMMの取得

https://github.com/pleriche/FastMM4
の右上の「DownLoad ZIP」ボタンを押してFastMM4-master.zipを取得する。

取得したzipファイルを展開する。

FastMM4BCB.cppに記載の手順

展開したフォルダの中にある FastMM4BCB.cpp のヘッダ部分にC++ Builderでの使用手順が記載されている。

手順

ソースフォルダへのコピー

1) Copy FastMM4BCB.cpp, FastMM4.pas, FastMM4Message.pas, FastMM4Options.inc, and FastMM_FullDebugMode.lib to your source folder.

上記5つのファイルをソース(Unit1.cpp)があるフォルダへコピーする。

FastMM_FullDebugMode.lib は FullDebugMode DLL\CPP Builder Support にある。

実行フォルダへのコピー

2) Copy FastMM_FullDebugMode.dll to your application's .exe directory (if you intend to use FullDebugMode).

FastMM_FullDebugMode.dll は FullDebugMode DLL\Precompiled にあった。

FastMM_FullDebugMode.dll をビルドで作成される .exeファイルの場所へコピーする (例: Win32/Debug/)。

プロジェクトへの追加とコンパイル

3) To your project, add FastMM4Messages.pas first, then FastMM4.pas, then FastMM4BCB.cpp. On compiling the .pas files, .hpp files are created and imported by the subsequent files.

3つのファイルをプロジェクトに追加しながら、一つ一つプロジェクトをビルドしてみる(ファイル単位でビルドしたら .hppが見つかりませんとなった?)。

プロジェクトファイルの書換え

4) Add USEOBJ("FastMM4BCB.cpp") to your project file, BEFORE any other USEFORM directives.

プロジェクトを閉じて、プロジェクト.cppファイルを書換える。

Project1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
...

を以下のようにした。

Project1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
USEOBJ("FastMM4BCB.cpp"); // 追加
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
...

プロジェクト設定の変更

5) Under the Project -> Options -> Linker menu uncheck "Use Dynamic RTL" (sorry, won't work with the RTL DLL).
FastMM will now install itself on startup and replace the RTL memory manager.

プロジェクトオプションの「C++リンカ」の「動的RTCとリンク」をfalseにした。

実行

作成したプロジェクトをビルドして実行し、ボタンを押してから終了すると以下のメッセージが表示された。

FullDebugMode

FastMMにはFullDebugModeというのがあり、ソースのどの場所がメモリリークかログを取れるそうなのだが、C++ Builderで試そうとしたら 「DebugGetMem ラベルがない」というエラーになってビルドできなくなった。

というのが昨日の試用だったのだが、以下の手順でうまく動作した。

プロジェクトオプションの設定

参考 http://mrxray.on.coocan.jp/Delphi/Others/UsageFastMM.htm

C++ (共有オプション) > 条件定義 に以下の4つ追加

  • FullDebugMode
  • EnableMemoryLeakReporting
  • LogMemoryLeakDetailToFile
  • ClearLogFileOnStartup

実行

プロジェクトをビルドしなおして、実行する。ボタンを押してメモリリークを発生させてアプリを終了する。

以下のファイルが Win32\Debug フォルダに作成されていた。
Project1_MemoryManager_EventLog.txt

上記のファイルに以下のような記述がある。

403FEE [Unit1.cpp][Unit1.cpp][Button1Click][19]

Unit1.cppの19行目でメモリリークが起きているとのこと。

19行目は以下。

    TStringList *lst = new TStringList();