ページ 11

メモリリークの検出

Posted: 2012年10月07日(日) 07:51
by zxc
  メモリリークの検出に_CrtSetDbgFlag関数を用いようとしていますが、上手くいきません。

コード:

#ifndef PART_H
#define PART_H
#include "part.h"
#endif

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>



int main(){
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


	part part_A;

	part* part_B_point;
	part_B_point = new part;

	delete part_B_point;//ここ//

	return 0;
}
  コンストラクタ、デストラクタはどちらも呼ばれた場合は分かるように、
文字列を表示するようにpart.hで実装しています。

  deleteの行をコメントアウトした場合には、呼ばれるデストラクタが、
呼ばれたコンストラクタより少ないので、メモリの解放ができていないと思うのですが、
出力ログにはコメントアウトの前後で変化は見られません。

  そこで聞きたいのですが、メモリリークのエラーが見られないのは、
1.他の部分にエラーが表示される。
2.コードが正しくない。
この二つのうちどちらか、もしくは両方だと思いますが、1ではないようですし、
2であれば、どこが間違っているのか見当がつきません。
そもそも注目する点が違うかもしれませんが、誤りを指摘していただけないでしょうか。

Re: メモリリークの検出

Posted: 2012年10月07日(日) 11:26
by softya(ソフト屋)
こんな感じで試してみましたが出力されています。
ただし出力先はコンソール画面ではなく出力ウィンドウです。

コード:

#define _CRTDBG_MAP_ALLOC
#include <stdio.h>
#include <crtdbg.h>

class part {
	int a;
public:
	part(int count) {
		a = count;
		printf("コンストラクタ%d\n",a);
	};
	~part() {
		printf("デストラクタ%d\n",a);
	};
};

int main(){
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


	part part_A(1);

	part* part_B_point;
	part_B_point = new part(2);

	//   delete part_B_point;//ここ//

	return 0;
}
結果。
Detected memory leaks!
Dumping objects ->
{87} normal block at 0x002C2B10, 4 bytes long.
Data: < > 02 00 00 00
Object dump complete.

あと、ヘッダの中なら分かるのですがcpp側ソースに書く意味がわかりません。
#ifndef PART_H
#define PART_H
#endif

【補足】
注意事項としてCTRL+F5(デバッグなしで開始)で実行してはいけません。

Re: メモリリークの検出

Posted: 2012年10月07日(日) 12:13
by zxc
  CTRL+F5で実行していました。そういうことでしたか。
F5のみでの実行で、検出できることを確認しました。

コード:

#ifndef PART_H
#define PART_H
#endif
  この部分は指摘されるまで気がつきませんでした。
多重インクルードの回避としてはcppに記述する方が一般的なのですね。
考えてみれば、一回の記述ですみますし・・・
ありがとうございました。解決とさせていただきます。

Re: メモリリークの検出

Posted: 2012年10月07日(日) 12:17
by softya(ソフト屋)
zxc さんが書きました: 
  この部分は指摘されるまで気がつきませんでした。
多重インクルードの回避としてはcppに記述する方が一般的なのですね。
考えてみれば、一回の記述ですみますし・・・
ありがとうございました。解決とさせていただきます。
cppではなくヘッダ側に記入するですよ。
cpp側に書いてもミスで多重インクルードする危険性が高いので意味が無いと思います。

Re: メモリリークの検出

Posted: 2012年10月07日(日) 12:39
by zxc
  すいません。逆でしたね;
ヘッダに書いておけば、何度も#ifndef~
と書かなくていい、ということですよね。

Re: メモリリークの検出

Posted: 2012年10月07日(日) 22:53
by n@it
さらに追加で書くと

コード:

::new(_NORMAL_BLOCK, __FILE__, __LINE__)
を、newの代わりにこっちを使うとリークしたときにどこで確保している領域なのかを検出してくれますので
つかってみるといいかとおもいます。