
環境:VC++6.0 MFC使用 ダイアログベースアプリケーション
使用PC:同一ソースをWin2000またはWinXPでリビルドして使用
です。
メインダイアログにメニューを実装し、あるメニュー項目を
選ぶと別のダイアログをDoModalで表示し、別のダイアログで「OK」を
押すとメインダイアログに処理が戻るようなソフトを作成しています。
別のダイアログは数種類あり、EDITボックスやコンボボックスなどを
配置しています。
ダイアログ切り替えの運用試験として、
あるダイアログを表示→閉じるを繰り返す試験を行っていると、
数時間でこのソフトが異常終了してしまいます。
(タイマ処理内で、現在日時分秒を出力しています)
「あるダイアログを表示」は、ソフトのタイマ処理で5秒おきにDoModalしています。
「閉じる」は、「OK」ボタンを押す別アプリを作成しています。
別アプリでは、「IsWindowVisible()の戻り値がTRUE」かつ
「FindWindowExを使用してlpszWindow(ウインドウ名)が「OK」」
のコントロールを探し出し、見つかればSendMessageなどで
「OK」ボタンを押す処理を代行させています。
何が原因で異常終了してしまうかを調べたいのですが、
具体的な良い方法はありませんでしょうか。
わかっている現象として、
1.タスクマネージャのプロセスタブで
このソフトのメモリ使用量を見ていると、
時間とともに少しずつ増加しています。
よろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
> CRTとは_CrtSetDbgFlag ... でしょうか?
御意。
> 異常の検出は無いようです。入れる場所が悪いのでしょうか。
悪いです。_CrtSetDbgFlagは起動直後など最初にやるものですので、
その位置でやっても恐らく結果が出てません。
最初に設定をしておいて、_CrtDumpMemoryLeaks等で結果を得ます。
# BoundsCheckerをお使いなら、近しい機能ともいえますが。
尚、デバッグ版実行時や上記設定時などはメモリがチェックの為に内部的に解放されず、
メモリが増え続けるように見えることがあります。
メモリ消費が増え続ける云々は、最低限リリース版で確認する必要があります。
# リリース版でもキャッシュのために解放されないものもありえますが。
また、staticなインスタンス内などで動的確保しても誤検出がありえます。
確証に至る情報はないのですが、何か漏らしてるとしたら、
DoModalで起動されるダイアログの中身の方じゃないですか?
再現コードがあるといいのですが、徐々に処理を削って公開できる
ものは作れませんか?(この過程で原因が分かることも多いので、
最小限の再現コードを作るのは王道ですが)
この回答への補足
MrBan様
ご回答いただきありがとうございます。
>悪いです。_CrtSetDbgFlagは起動直後など最初にやるものですので、
>その位置でやっても恐らく結果が出てません。
>最初に設定をしておいて、_CrtDumpMemoryLeaks等で結果を得ます。
初めて使用したこともあり、勉強不足でした。
ご指摘ありがとうございます。
MSDNで調べてみましたが、コードの記述位置について教えていただけませんでしょうか。
1.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
は、
BOOL CxxxApp::InitInstance()
のあるファイルの
#include
の行の後に記述
2.
_CrtDumpMemoryLeaks
は、
BOOL CVisionSoftApp::InitInstance()
の一番最後に記述
3.
_CrtSetDbgFlag
は
BOOL CVisionSoftApp::InitInstance()
の一番最初に記述
でよいのでしょうか。
質問が増えてしまいますがすみません。
新たに新規プロジェクト(ダイアログベース)を作成し、上記の3つのコードのみを追加し
実行したところ、
「プロジェクト」メニュー→「設定」→「一般」タブ「Microsoft Foudation Class」で
「共有DLLでMFCを使用」にした場合、実行してすぐに「OK」を押してもリークが発生し、
「MFCのスタティックライブラリを使用」に設定した場合、実行してすぐに「OK」を押してもリークは
発生しませんでした。
これは、「共有DLLでMFCを使用」にした場合、DLLに問題がありリークが発生している
と考えてよいのでしょうか。
>メモリ消費が増え続ける云々は、最低限リリース版で確認する必要があります。
># リリース版でもキャッシュのために解放されないものもありえますが。
これは、「タスクマネージャ」の「メモリ使用量」の値に惑わされてはいけないということでしょうか。
メモリ消費が増加しても、延々と増加する場合は問題ですが、
起動後増加していても、ある地点で安定していれば問題ないということでしょうか。
>確証に至る情報はないのですが、何か漏らしてるとしたら、
>DoModalで起動されるダイアログの中身の方じゃないですか?
>再現コードがあるといいのですが、徐々に処理を削って公開できる
>ものは作れませんか?(この過程で原因が分かることも多いので、
>最小限の再現コードを作るのは王道ですが)
はい、メイン画面(起動後初期表示される画面)を表示したままであれば
「メモリ使用量」は増えませんが、DoModalでダイアログを表示すると
「メモリ使用量」が増えていくことがあります。
おそらく、DoModalで起動されるダイアログの方に問題があると思っています。
機能を削ったコードを用意しますので申し訳ありませんが、
少し時間をいただけませんでしょうか。
頼ってばかりで申し訳ありませんが、もう少しの間ご指導お願いいたします。
No.1
- 回答日時:
症状からみて、メモリリーク(バグ)してる可能性もありそうです。
異常終了はメモリ確保失敗の結果、不正参照とかですかね…?
もしくは、タイミング問題のバグとか。
いずれにせよ、ちゃんとデバッグしてください。
VCならCRT(C Runtime)にメモリリークチェック機能がありますので、
多少は役に立つかもしれません。調べてみてください。
市販のメモリチェッカなども販売されてますが、今更VC6版があるかどうか…。
この回答への補足
チェックツールは、BoundsCheckerを使用していますが、
ソフト動作中は異常の検出は無いようです。
CRTとは
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
でしょうか?
各ダイアログのOnOKの最後に入れていますが、
異常の検出は無いようです。入れる場所が悪いのでしょうか。
「タイミング問題」については、なんともいえませんが、
void CVisionSoftDlg::OnTimer(UINT nIDEvent)
{
static long lDlgCount = 0;
switch( nIDEvent )
{
case ID_TIMER_1 :
KillTimer( ID_TIMER_1 );
switch( lDlgCount )
{
case 0 :
// ダイアログ1 DoModal()
break;
・・・
case 9 :
// ダイアログ10 DoModal()
break;
}
lDlgCount++;
if( 10 < lDlgCount )
{
lDlgCount = 0;
}
SetTimer( ID_TIMER_1, ID_TIMER_1_INTERVAL, NULL );
break;
default :
break;
}
CDialog::OnTimer(nIDEvent);
}
のようにして、前のダイアログの終了処理が終わる前に
次のダイアログが表示されないようにはしているつもりです。
私としては、
>1.タスクマネージャのプロセスタブで
>このソフトのメモリ使用量を見ていると、
>時間とともに少しずつ増加しています。
が気になっています。
上の現象=リークと考えてよいものでしょうか。
他に気にする点がありましたらご指摘お願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- ビデオカード・サウンドカード PCに接続したイヤフォンのマイクが使えません。 3 2022/10/22 11:07
- Windows Me・NT・2000 widows xpのエラーで利用ができなくなりました 3 2022/12/21 13:43
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- Visual Basic(VBA) エクセルVBA コードが同じでもファイルによって処理速度が大きく変わるのはなぜ 5 2022/11/06 21:34
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/06 17:46
- その他(プログラミング・Web制作) 三菱製PLC Qシリーズで技術的なことをご教示いただければ幸いです。使ってるソフトはGXWorks2 1 2023/02/28 12:07
- マウス・キーボード キーボード設定で困っています。長文です。 2 2022/12/10 12:44
- Visual Basic(VBA) ExcelからAccessのテーブルに書き込む時に時間がかかる 1 2022/10/14 20:38
- Excel(エクセル) excelvbaでスライドショーを作りたい 2 2023/04/20 14:32
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
メモリのセグメント違反の解決...
-
計算速度が遅い
-
VBAの配列サイズとメモリに関して
-
メモリが不足しています(VBA)
-
PC-98で拡張メモリを使え...
-
C言語で、メモリを解放しないで...
-
変数のスコープはどうするのが...
-
メモリ不足
-
malloc関数の使い終わった後の...
-
ルネサスマイコン(R8C) ビルド...
-
エクセルのメモリ使用状況/Appl...
-
「memcpy」と「strcpy」について
-
組み込み系でのmallocについて
-
エクセルVBA 大容量CSVファイル...
-
バッチファイルでの実行EXEのメ...
-
コンパイラの違いについて
-
Macターミナルで実行中のプログ...
-
家電製品の電力周波数を変える機械
-
バックグラウンドのプロセスの...
-
C# シリアル通信でデータ受信...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
メモリが不足しています(VBA)
-
メモリのセグメント違反の解決...
-
「memcpy」と「strcpy」について
-
メモリ不足
-
「ヒープサイズの設定」て何?
-
エクセルのメモリ使用状況/Appl...
-
C言語における再帰呼び出しの...
-
ファイルマッピング関数で失敗
-
ExitProcessの関数コールについ...
-
EXCEL-VBAにてADOのレコードセ...
-
エクセルVBA 大容量CSVファイル...
-
ExcelのVBAでメモリ解放できない
-
メモリを解放しないとどうなる?
-
バッチファイルでの実行EXEのメ...
-
Bitmapを重ね合わせる方法
-
ルネサスマイコン(R8C) ビルド...
-
C,C++プログラムの強制終了時の...
-
C言語:関数のメモリ上でのサイ...
おすすめ情報