MainWndの開放について

解決


浅草  2008-05-05 11:11:43  No: 68238

// 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 11:27:49  No: 68239

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

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


浅草  2008-05-05 17:18:59  No: 68240

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

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

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


Blue  2008-05-06 11:34:33  No: 68241

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

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

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


浅草  2008-05-07 00:20:20  No: 68242

>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を入れているのだと思います。

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加