c++ builder / memory leak > FastMM試用

```txt:動作確認
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にした。


### 実行

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

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5952440f-5ef5-0a27-e6bf-9da2f8d2eb6c.png)


## 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行目は以下。

```cpp
	TStringList *lst = new TStringList();
```