- ベストアンサー
メモリのエラーに関する問題
- VC++6.0のMFCでViewクラスとDialogクラスがあり、ファイルオープン後に構造体を作成しメモリを取得、ダイアログで値を表示するという処理が行われています。
- 最初の処理では問題なく動作しますが、2回目の処理でエラーが発生し、エラーを回避するためにデストラクタでメモリを解放する必要があります。
- エラーが発生するのは、2回目の処理でファイルオープンダイアログにて開くを押さない場合です。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
>2回目はファイルオープンダイアログにて開くを押さない >結果:エラー 予想1 ダイアログで「開く」を押してない時も、Viewクラスのオブジェクトをコンストラクトしてしまっていて、コンストラクトしただけで何もしてない。 そして、デスクトラクタに来た時に「1回目で使い終わってメモリを開放しちゃってる構造体を、メモリ確保してないのに再度メモリ開放しようとして、エラーになっている。 予想2 2回とも「開く」を押さなかったとき、構造体を示すポインタ変数は「初期化時にNULLか何かになっている」ので、デスクトラクタに来た時にポインタ変数がNULLなので、何もエラーが起きない。 原因予想 「開くを押したかどうか?」を判断する前に、Viewクラスのオブジェクトをコンストラクトしているのが原因。 予想される修正方法 「開くを押したかどうか?」を判断する前は、一切の変数、オブジェクトをコンストラクトしないようにする。 駄目な例 関数(~~~) { ViewClass View; //ここでコンストラクトすると… 構造体の変数 = NULL; オープンダイアログ表示 if (開いたを押したか?) { 構造体をメモリ確保 (中略) } //この位置で、つまり関数を抜ける時にデクストラクタが呼ばれ、確保してない構造体を開放しようとしてしまう。 } 良い例 関数(~~~) { 構造体の変数 = NULL; オープンダイアログ表示 if (開いたを押したか?) { ViewClass View; //ここでコンストラクトすると… 構造体をメモリ確保 (中略) //この位置、if文を抜ける時にデクストラクタが呼ばれ、構造体を確保した時だけしか開放しない。 } } で、デクストラクタでは if (構造体の変数 != NULL) { 構造体を開放 構造体の変数 = NULL; } と書いて「NULL以外の時だけ開放する」「開放直後は必ずNULLにする(開放した後のゴミの値を残さない)」ようにしておく。 もちろん「最初に1回しか通らない所で、必ずNULLで初期化しておく」のも忘れずに。
補足
勉強になりました。ありがとうございました。