ポインタの初期化関数内におけるdelete[]操作で,実行不可

[戻る]
merlo 2002/04/30(火) 16:00:36
どうもこんにちは
merloです.

相変わらず画像処理ソフトを作っています.
どれもこれもみなさまのおかげです.

作業状況:
 Win2k VC++6.0 MFC DLGベース

新規作成からの変更箇所:
 class CCGDlg : public CDialog(←ヘッダファイルになります)
        public:
             char*          m_clr_img;       //カラー画像情報記憶
             unsigned char* m_mono_img;      //モノクロ画像情報記憶
             unsigned char* m_mono_img_back; //モノクロ画像情報記憶バックアップ
 BOOL CCGDlg::OnInitDialog()
     // TODO: 特別な初期化を行う時はこの場所に追加してください。
     if(m_clr_img!=NULL)  delete[] m_clr_img       ;
     if(m_mono_img!=NULL) delete[] m_mono_img      ;
     if(m_mono_img_back)  delete[] m_mono_img_back ;

こんな風に,クラス内で宣言し,初期化関数内にて中身をからっぽに
しているつもりなのに,プログラム起動時にエラーが発生してしまい
初期化に失敗してしまいます.
new と delete は一対になっていることは知っていますが,
この場合はnew 関数が現れていないからでしょうか.

ただし,クラス内で宣言したポインタ変数をグローバル変数(つまりCPPファイルの
中で,さらにどの{}にも含まれない箇所で宣言)にすれば,起動時における
初期化失敗は発生しません.

これに関して,どなたかご存知な方がいらっしゃったら,
どのようなことでもかまいません.
レスください.

よろしくお願いします

merlo

 

不良PG [E-Mail] 2002/04/30(火) 16:36:49
>プログラム起動時にエラー
エラーが起こるのは、どの場所ですか?
デバッカで追って特定しましょう。


おそらくこれが足りないとか・・
void CCGDlg::CCGDlg
{
  m_clr_img = NULL;
  m_mono_img = NULL;
  m_mono_img_back = NULL;
}

Bun 2002/04/30(火) 16:48:53
ダイアログのコンストラクタで

m_clr_img = NULL; // として初期化します(その他のポインタも)

#エラーの内容は、デバッグモードで、merloさんが危ないことをやっているのを
#指摘しているのです。
#ポインタを初期化していないので、m_clr_imgにはある不定なアドレスが入っていて
#その領域を開放しちゃ、まずいですよね。アドレスが何を指しているのか
#わからないのだから。
#というわけで、ポインタはコンストラクタでNULLに初期化する習慣をつけましょう。

>if(m_clr_img!=NULL)  delete[] m_clr_img;

ifは不要です。単に

delete[] m_clr_img;

でよいようです。NULLのdeleteは文法的にも問題ありません。
ただし、[]がつくのはnewで配列を確保した場合です。
                         ^^^^^^^^^^
#おまけ

char* m_clr_img; // は、ポインタであることがわかるように

char* m_pClr_img; // などとしましょう

Bun 2002/04/30(火) 16:50:58
うへェ、かぶかぶり〜ん。ぴろりろり〜ん。(爆)

ゴミです。m(__)m

merlo 2002/04/30(火) 17:41:52
不良PG 様  Bun 様

早速のサポート誠にありがとうございます.
さっそく,クラスのコンストラクタにて
”=NULL"にて,初期化したら
うまく行きました!!

#というわけで、ポインタはコンストラクタでNULLに初期化する習慣をつけましょう。

↑ はい!!

ところで,コンストラクタは,

CCGDlg::CCGDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CCGDlg::IDD, pParent)

これですよね.当然のようですが,引数がやや多いので,
確認させてください(>_<)

Bun 2002/04/30(火) 18:04:33
>CCGDlg::CCGDlg

正解。

 By もんた

merlo 2002/04/30(火) 20:09:54
[[解決]]
皆様の助言のおかげで無事プログラム作成を
進めることができました.

ありがとうございました.

2002/05/01(水) 10:39:21
どうでもいいかもしれませんが、ちょっと気になりました。
OnInitDialog() で delete[] するって、なんかしっくりこなくありません?
初期化すべきときに後始末っぽい処理があるっていうのが、
まあいろいろあるんでしょうけど・・・

[E-Mail] 2002/05/01(水) 13:10:59
> OnInitDialog() で delete[] するって、なんかしっくりこなくありません?
> 初期化すべきときに後始末っぽい処理があるっていうのが、

そのクラスの使われ方によってはありだと、思います。

void hoge::hoehoe()
{
    CxxxDlg dlg ;
    dlg.DoModal() ;  // ダイアログ表示
    // なんか処理
    dlg.DoModal() ;  // ダイアログ表示
}

なんて事していて、CxxxDlg のがダイアログ起動中に情報を蓄積していく
ような機能を有していたりすれば。
ようするに、「使いまわす可能性があるんで、そのつど初期化」って事に
なるんでしょうか。

2002/05/01(水) 15:36:58
なるほど
>  dlg.DoModal() ;  // ダイアログ表示
>  // なんか処理
>  dlg.DoModal() ;  // ダイアログ表示
の なんか処理 の部分で、dlgが作った動的なメモリを参照する、と。
ならアリですね。

古いスレッドには追加発言できません。