ダイアログ画面を強制的に閉じたときにメモリリーク? – プログラミング – Home

ダイアログ画面を強制的に閉じたときにメ...
 
通知
すべてクリア

[解決済] ダイアログ画面を強制的に閉じたときにメモリリーク?


ぽっぽ
 ぽっぽ
(@ぽっぽ)
ゲスト
結合: 14年前
投稿: 4
Topic starter  

お世話になります。環境はVC++2005 + MFCです。

ダイアログベースでプロジェクトを新規作成し、ビルド、実行してモーダルダイアログ
画面を表示します。ここで、「OK」、「キャンセル」ボタンではなく、画面右上の「×」印を
クリックして画面を閉じると、次のようなメッセージが出て終了します。

ネイティブ' はコード 2 (0x2) で終了しました。

リソースの解放がなされていないようです。WM_DESTROYメッセージに対応したハンドラ
(OnDestroy)でリソースの解放をやろうとしていますが、どうやれば解放できるのかわか
りません。リソースの解放は無理なのか、あるいはできるのならその方法をご教示いた
だければ幸いです。

【追記】
数年前に作成されたアプリケーションが、どういうわけか「OK」、「キャンセル」ボタンを
取り去って、「×」印で終了する仕様になってました。画面にたくさんのコントロールが
配置されているので作り直すのは大変です。せめて、「×」を押したときにメモリリーク
が出ないようにしたいのです。


引用未解決
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

終了しているんだからリークしてても何の問題もないのでは?


返信引用
ぽっぽ
 ぽっぽ
(@ぽっぽ)
ゲスト
結合: 14年前
投稿: 4
Topic starter  

レスありがとうございます。

>終了しているんだからリークしてても何の問題もないのでは?

まぁ、そうなんですが。。。しかし、爆弾抱えているようで。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

っていうか「本当にリークしているかどうか」はきっちり調べ済みなの?
何をもって「リークしている」と判断したわけ?

ウチの VS2005 で MFC Dialog App をアプリケーションウイザードで新規作成し
一切何の変更も加えずそのままビルド・実行して
・×ボタンで閉じると 終了コード 2
・エスケープキーでキャンセルして閉じると 終了コード 27
・OK/キャンセルボタンをクリックして閉じると 終了コード 0
になる。多分この状態では、なんもリークしていないと思われるわけだが。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

ダイアログアプリの終了コードはダイアログの終了時に
操作したボタン等によって変わるので0が返って来るのが
正しいと言う考えでいるのであれば間違いですね。

デバッグモードで動かしている時に終了時にアウトプットウインドウに
メモリリークの表示が出ているのであれば、まだわかりますけれど。
但し、デバッガーに出てくるメモリリークの表示もMFCの終了処理によるもの
なので、STLやらシングルトンインスタンスやらが絡むと実際には問題なくても
出てくる事はあると思います。
(要はチェックした時に確保状態(未開放)なのかという話なので)


返信引用
ぽっぽ
 ぽっぽ
(@ぽっぽ)
ゲスト
結合: 14年前
投稿: 4
Topic starter  

そうですか。。。確認はしていません。

ただ、「終了コード 2 (0x2)が出るのでなんだろう?」とGoogleで検索したら
「メモリリークの可能性」という記述がいくつかヒットしたので、そう思って
しまいました。

よく考えてみれば、新規作成したデフォルトのダイアログ画面の右上にある
「×」印をクリックして画面を閉じたら「メモリリークが生じる」というのなら、
MFCが「×」印のついたダイアログ画面をデフォルトで用意するはずもないと
思います。

tetrapodさんの言われるように、メモリリークの可能性は低いということで
あれば、数年前のプログラムを安心して改良できます(別の爆弾抱えている
可能性もありますが)。


返信引用
ぽっぽ
 ぽっぽ
(@ぽっぽ)
ゲスト
結合: 14年前
投稿: 4
Topic starter  

返事が遅れてしまいました。PATIOさん、ありがとうございます。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

VC6とVC7.1のMFCをざっと見た感じでは、

1)モーダルダイアログをメインにすると、
 ダイアログはInitInstanceの中で開始され、
 ダイアログ終了時にInitInstanceはFALSEを返す。

2)AfxWinMain中でInitInstanceがFALSEを返すと、
 AfxWinMainはExitInstanceの戻り値を返し、
 プロセスが終了する。

3)ExitInstanceはPeekMessageが最後に処理したメッセージの
 WPARAMを返す(vc7.1ならAfxGetCurrentMessageで取得可)。

ExitInstanceのソースのコメントでは最後のメッセージはWM_QUITなので
普通はPostQuitMessage(0)の引数ゼロが返るはずだが、

モーダルダイアログをメインにした場合、
ESCキーを押した場合はWM_KEYDOWNが最後のメッセージとなる(wParam = 0x1b)。
Xボタンやシステムメニューの閉じるの場合は、
PostMessage(WM_COMMAND wParam = 2)が最後のメッセージになる。
こんな感じのようです。

このスレのテーマからは外れますが、
本来WinMainはゼロを返すべきなので、何か工夫が必要と思います。~~


返信引用
ryo
 ryo
(@ryo)
ゲスト
結合: 23年前
投稿: 252
 

MS純正のダイアログベースの仕様だってことがわかっていれば、
VSユーザー(うちらプログラマたち)としては
十分なんじゃないかな?
工夫して0を返すようにする必要はないように思えますが・・・

ただ、
この仕様について、MSの公式な文章はあるのか(MSDN内とかに)?
この値をプログラマたちはどう利用することが想定されているのか?
そもそもなんでこんな仕様なのか?
・・・なぞではありますが


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

え~と、一応指摘しておきますが、WinMain()が0を戻すのは

「WinMainがメッセージループの処理をしないで終了する」
ときなので、意味的には「起動の失敗」ですね。

WinMainが戻すのは最終メッセージ(WM_QUIT)のwParam
なので、原理的には

「0以外は全て正常」

です。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

ごめん。まちがった

「0以外は全て正常。0の場合、失敗の可能性がある」

従って、WinMainの戻り値からは一般に

「何も分からない」


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

病的な例
#define IDC_BUTTON1 259

PostMessage(WM_COMMAND, IDC_BUTTON1);

void OnButton1()
{
 EndDialog(IDCANCEL);
}

終了コードは259
つまり、GetExitCodeProcessの戻り値も259 == STILL_ACTIVE

まぁ、これはこれでいいんですけど。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

>「0以外は全て正常。0の場合、失敗の可能性がある」
未処理の例外で終了した場合はGetExceptionCode()が返るようですが。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

>未処理の例外で終了した場合はGetExceptionCode()が返るようですが。

ですか。知りませんでした。
crtのメインまでロングジャンプしているんですかね(う~む)。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました