こんにちは。
私の作成しているプログラムに、メモリリークが発生していると言われました。
_CrtDumpMemoryLeaks();を使用して確認してみると、
確かにメモリリークが起きていると表示が出ています。
_CrtDumpMemoryLeaks();を使って、1行、1行どこでリークが発生しているかを確認したところ、ダイアログを宣言しているところでリークが始まっていました。
CClsDlg dlg;
のような感じで宣言しているだけなのですが、何か誤りがあるのでしょうか?
また、メモリリークを無くすためには、1行、1行こうやって確認していくしかないのでしょうか?
よろしくお願いします。
ビジュアルスタジオ2005にてMFCを使ってプログラムを作成しています。
メモリリーク!
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: メモリリーク!
MFCなら_CrtDumpMemoryLeaks();を呼ばなくてもデバッグビルドなら呼び出されるはずですので見当違いです。
あと、細かいポイントで_CrtDumpMemoryLeaks();を呼び出したらリークしているのはあたりまえです(確保されたメモリが解放されているはずがない)。なのでプログラムの最後に呼ぶのが正しいです。
「メモリリークを検出するには」
http://www.hiramine.com/programming/win ... yleak.html
MFCの場合は、こういう追跡方法があります。
「MFC におけるメモリ リークの検出」
http://msdn.microsoft.com/ja-jp/library ... s.80).aspx
DEBUG_NEW の働きでリークした場所は特定できるはずです。
「メモリリークのメモリ確保場所を特定するには」
http://www.hiramine.com/programming/win ... yleak.html
あと、細かいポイントで_CrtDumpMemoryLeaks();を呼び出したらリークしているのはあたりまえです(確保されたメモリが解放されているはずがない)。なのでプログラムの最後に呼ぶのが正しいです。
「メモリリークを検出するには」
http://www.hiramine.com/programming/win ... yleak.html
MFCの場合は、こういう追跡方法があります。
「MFC におけるメモリ リークの検出」
http://msdn.microsoft.com/ja-jp/library ... s.80).aspx
DEBUG_NEW の働きでリークした場所は特定できるはずです。
「メモリリークのメモリ確保場所を特定するには」
http://www.hiramine.com/programming/win ... yleak.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
-
みるくる
Re: メモリリーク!
>MFCなら_CrtDumpMemoryLeaks();を呼ばなくてもデバッグビルドなら呼び出されるはずですので見当違いです。
これは「出力」に特に何も表示されていなければ、メモリリークは起きていないということですか?
うまく動作しなかったプログラムの動きを見ようと、ログを出力するようにしたら、うまく動作するようになった場合、これはメモリリークなのでしょうか?
各プログラムソースの間にログ出力の処理を入れただけなので、全体の処理としては何も変わっていないはずなのに動くようになってしまったので、もう、わけがわからないのです。
すいません。メモリリークのデバッグなんて初めてなので、右も左もわからないのです。
プログラムの最後に呼び出したら、やはりメモリリークが起きているような出力がされました。
何か、取り留めの無い文章になってしまいましたが、よろしくお願いします。
これは「出力」に特に何も表示されていなければ、メモリリークは起きていないということですか?
うまく動作しなかったプログラムの動きを見ようと、ログを出力するようにしたら、うまく動作するようになった場合、これはメモリリークなのでしょうか?
各プログラムソースの間にログ出力の処理を入れただけなので、全体の処理としては何も変わっていないはずなのに動くようになってしまったので、もう、わけがわからないのです。
すいません。メモリリークのデバッグなんて初めてなので、右も左もわからないのです。
プログラムの最後に呼び出したら、やはりメモリリークが起きているような出力がされました。
何か、取り留めの無い文章になってしまいましたが、よろしくお願いします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: メモリリーク!
MFCのデバッグビルドなら何もしなくて良いです。と言うよりMFCのフレームワークの仕組み上_CrtDumpMemoryLeaks();を呼ばないでください。
そもそもメモリリークされているというのは誰が、どの手段で確認したのでしょうか?
そもそもメモリリークされているというのは誰が、どの手段で確認したのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: メモリリーク!
MFCでシンプルなダイアログを作ってリークさせてみました。
出力に表示されたリークのレポートです。
{365} normal block at 0x0061F510, 4 bytes long.
の方は行番号が不明ですが、mallocした方です。わかりづらいですね。C++ではもこう言う意味でもmallocは避けてください。
mfctestdlg.cpp(101) : {364} normal block at 0x00612F28, 4 bytes long.
はnewの方ですがnewを行った行番号を確認できます。
ちなみに_CrtDumpMemoryLeaks();を呼びだしてはいませんよ。
//コードを一部抜粋
BOOL CMFCtestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// "バージョン情報..." メニューをシステム メニューに追加します。
// IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
// Framework は、この設定を自動的に行います。
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
// TODO: 初期化をここに追加します。
int *reek = new int;
int *reek2 = (int*)malloc(sizeof(int));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}Dumping objects ->
{365} normal block at 0x0061F510, 4 bytes long.
Data: < > CD CD CD CD
c:\users\softya\documents\visual studio 2008\projects\mfctest\mfctest\mfctestdlg.cpp(101) : {364} normal block at 0x00612F28, 4 bytes long.
Data: < > CD CD CD CD
Object dump complete.の方は行番号が不明ですが、mallocした方です。わかりづらいですね。C++ではもこう言う意味でもmallocは避けてください。
mfctestdlg.cpp(101) : {364} normal block at 0x00612F28, 4 bytes long.
はnewの方ですがnewを行った行番号を確認できます。
ちなみに_CrtDumpMemoryLeaks();を呼びだしてはいませんよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: メモリリーク!
そういうときはバッファオーバーランを疑ったほうが良いかもしれません。みるくる さんが書きました:うまく動作しなかったプログラムの動きを見ようと、ログを出力するようにしたら、うまく動作するようになった場合、これはメモリリークなのでしょうか?
各プログラムソースの間にログ出力の処理を入れただけなので、全体の処理としては何も変わっていないはずなのに動くようになってしまったので、もう、わけがわからないのです。
配列の確保した要素数を超えた添字を指定してアクセスするといった、不正なメモリアクセスです。
メモリリークとは異なります。
デバッグにおいては、むしろ何も変わっていない状況を作る(バグ発症時の状況を再現する)ことが極めて難しいです。
すべてを疑ってください。