MainWndの開放について

解決


浅草  2008-05-05 02:11:43  No: 68238  IP: [192.*.*.*]

// CWinApp派生
CWinXXXApp::InitInstance()
{

    ・・・・

  CWinMine* pMine = new CWinMine;
  m_pMainWnd= (CWnd*)pMine;
  pMine.Create(...);
  pMine.ShowWindow(...);
}
CWinXXXApp::~CWinXXXApp(){
  delete (CWinMine*)pMine; 
}

とすると、メモリリークが残ってしまい、いろいろ試した結果、

void CWinMine::PostNcDestroy()
{
  CWnd::PostNcDestroy();
  delete this;
}

と、自信のCWnd派生クラス側自身をdeleteしたところ、メモリリークはなくなりましたが、この処理が正しいのか、なぜ外部からdeleteを呼ぶとメモリリークが発生するのか、よくわかりません。

ご教授お願いします。

編集 削除
Blue  2008-05-05 02:27:49  No: 68239  IP: [192.*.*.*]

>  pMine.Create(...);
>  pMine.ShowWindow(...);
は間違っているようですが、本当に提示されている内容だけでしょうか?

デストラクタではなくExitInstanceでdeleteするとどうなりますか?

編集 削除
浅草  2008-05-05 08:18:59  No: 68240  IP: [192.*.*.*]

返信ありがとうございます。
pMine->Create(...);
pMine->ShowWindow(...);
ですね。
パタパタと書いたので間違いました。

ExitInstanceで、deleteしても同じでした。

多分、CWinApp内部でm_pMainWndを開放していたりしていて、それで、CWnd継承先のCWndMineのデストラクタが呼ばれないのかなあ、などと思っているのですが、、、。

編集 削除
Blue  2008-05-06 02:34:33  No: 68241  IP: [192.*.*.*]

>多分、CWinApp内部でm_pMainWndを開放していたりしていて、
>それで、CWnd継承先のCWndMineのデストラクタが呼ばれないのかなあ、などと思っているのですが、、、。
virtualではないデストラクタなんでしょうか?
(というか、CWinApp内部ではm_pMainWndを開放しないとおもう)

メインとなるウィンドウであれば、モードレスで表示する必要はあるのでしょうか?


ちなみに、デストラクタで解放できないのはAfxWinMain関数内でInitInstanceメソッド呼び出し後、
m_pMainWndがNULLでないとき、m_pMainWndに対してDestroyWindowメソッドを呼び出します。
DestroyWindowでm_pMainWndにNULLが設定されていまい解放できなくなります。
(デバッガで追えばわかります。)

編集 削除
浅草  2008-05-06 15:20:20  No: 68242  IP: [192.*.*.*]

>virtualではないデストラクタなんでしょうか?
virtualです。
>>CWndMineのデストラクタが呼ばれない
実行時にあわせて適切なアドレスが呼ばれるんでしたっけ?
ナンセンスでした。

>デストラクタで解放できないのはAfxWinMain関数内でInitInstanceメソッド呼び出し後、
>m_pMainWndがNULLでないとき、m_pMainWndに対してDestroyWindowメソッドを呼び出します。
>DestroyWindowでm_pMainWndにNULLが設定されていまい解放できなくなります。

書いていませんでしたが、InitInstanceでtrueを返しているので、InitInstance後はThread->runに入っています。その後、メッセージループを終了して、ExitInstanceに入る時には、既にm_pMainWndはNULLになっていました。

確認はできませんでしたが、終了時のメッセージループのどこかで、m_pMainWndを開放せずにNULLを入れているのだと思います。

とりあえず、それ以外考えられないとこまで来たので解決とします。
ありがとうございました。

編集 削除