MFCでメンバインスタンスがnewできない

[戻る]
ガガガ 2013/08/27(火) 16:19:59
Visual Studio 2012を使用しております。

手製のクラスCLを定義し、このクラスの.hに

class CL
{
private:
 bool flag;
public
 bool Getflag(){return flag;}
}

と書き、クラスのコンストラクタには
CL::CL()
{
 flag=false;
}
と書きました

このクラスのポインタをViewクラスのメンバに

CL * cl[20]

と置き、ViewクラスのOnCreateに、

for(int yy=0;yy<20;yy++)
 cl[yy]=new CL();

OnCloseに

delete[] cl;

と置きました。

このプロジェクトは、ビルドは通りますが、
実行直後、ブレークポイントで止めて、newした後のclの要素の中身をみると
0x00000000や0xfeeefeee、0xababababといった不自然なアドレスが格納されており
flagの値も???でした。

このような場合、どのような原因や対策が考えられますでしょうか。

よろしくお願い致します。

επιστημη 2013/08/27(火) 22:03:22
> 実行直後、ブレークポイントで止めて、newした後のclの要素の中身をみると

> 0x00000000や0xfeeefeee、0xababababといった不自然なアドレスが格納されており

> flagの値も???でした。



break point で停まった時点で OnCreateは通過しているのでしょうか?

ガガガ 2013/08/28(水) 09:24:57
はい。OnCreate内でnewしたあと、、別の関数に飛ばし、そこでブレークポイントを

張ってみたら、上記のようなおかしなことになっていました。



配列かポインタが、設計上書き換えない個所を誤って書き換えている可能性もあるので

いまそこらへんを重点的に調べています。

ガガガ 2013/08/28(水) 09:48:21
調べてみて一つわかったことは、上記で別の関数に飛ばした後、for文を使った

途端に、カウンタ用変数だけでなくthisポインタのアドレスを書き換えている

ことでした。

for文は、

    for( xx=0;xx<20;xx++)



という程度の難しいものではありませんが、ここを通過するとき、thisポインタが

書き換えられたりメンバ変数のいくつかが<メモリを読み取れません>になったり

していました。

このようなことは、起こりえるのでしょうか。だとすれば、どのような対策が

必要でしょうか。

Kelly 2013/08/28(水) 10:34:56
配列自体がnewで生成されているのではなく
配列の要素が各々newで生成されているとしたら、

for (int yy = 0; yy < 20; yy ++)
  delete cl[yy];

こうなるのでは?

ガガガ 2013/08/28(水) 10:47:33
>for (int yy = 0; yy < 20; yy ++)

>  delete cl[yy];



おっしゃる通りです。最初のビルドのとき、警告がみえましたので、このことだと思われ
ます。

紅' 2013/08/28(水) 18:06:39
こんにちわ。
まだ解決していないのですよね?
確認をさせてください。

・デバッグモードでビルドしていますか。
 ビルド時の設定が、ステップ実行に適したものになっていますか。

・「不自然なアドレスが格納されている」というのは、
 new をしてから delete をする前までのいずれかのタイミングでと
 いうことでよいですか。

・「thisポインタのアドレスを書き換えている」 for 文とは、
 new を行っている for 文ですか。別の for 文ですか。

・前項が「別の for 文」である場合、new の for 文の直後でそのポインタを使用して
 メソッドなどを呼び出した場合に正常動作をしますか。

・this ポインタとはどこの this ポインタのことをいっていますか。
 new で生成した CL クラスのインスタンス内での this ポインタですか。
 この場合、new した配列には「不自然なアドレスが格納されている」はずなのですが
 CL クラス内のメソッドなりに正常にステップインできたということですか。

・提示されたコードでその現象は再現しますか。
 おそらく実際のコードから説明に必要な部分だけを抜き出したのだろうと思いますが、
 これが正しい場合に、たとえば
 - 提示のコードで new している部分が、
  要素数固定の配列にではなく動的配列を生成して、、とか
 - new している部分が別の関数内にあって配列 cl をその関数に値渡ししていたりとか
 - 配列 cl のスコープが new した個所と
  「不自然なアドレスが格納されている」と判断した個所とで別だったりとか
 などということはありませんか。
 ※その場合、もとの配列のポインタが指す先と違うところに CL の
  インスタンスを作っていたりするかもしれません

0xfeeefeee とかはデバッグモードで実行したときに初期化していないポインタに
デバッガ(VS)が仮に設定する値だったと思うので、そもそも new が成功していないか、
別の場所に結果を保存しているかじゃないかと思うのですが。

それで、不正なポインタ経由でメソッドなどを呼び出ししているから
ステップインしたときにメンバ変数が見えなかったり、
その中でメモリに関する操作をしてメモリ破壊をしていたり、とか。

ガガガ 2013/08/28(水) 18:32:57
[[解決]]
・デバッグモードでビルドしていますか。
 ビルド時の設定が、ステップ実行に適したものになっていますか。
→リリースモードになっていました。

・「不自然なアドレスが格納されている」というのは、
 new をしてから delete をする前までのいずれかのタイミングでと
 いうことでよいですか。
→newの直後です。

・「thisポインタのアドレスを書き換えている」 for 文とは、
 new を行っている for 文ですか。別の for 文ですか。
→別のfor文です。whileも試しましたが、なぜか書き換わっていました。


・前項が「別の for 文」である場合、new の for 文の直後でそのポインタを使用して
 メソッドなどを呼び出した場合に正常動作をしますか。
→正常に動作します。

・this ポインタとはどこの this ポインタのことをいっていますか。
 new で生成した CL クラスのインスタンス内での this ポインタですか。
 この場合、new した配列には「不自然なアドレスが格納されている」はずなのですが
 CL クラス内のメソッドなりに正常にステップインできたということですか。
→C***Viewのthisです。メソッドにステップインしています。

・提示されたコードでその現象は再現しますか。
→私の環境では再現できるのですが、他の環境ではわかりません。

ここまで書いておいて、ふと気になったのでデバッグモードにしたら、
正常に動作しました。
とんでもない凡ミスでした。
お騒がせしてしまい、申し訳ございません。

紅' 2013/08/29(木) 09:30:26
解決したようでなによりです。
最初のは半ば冗談で書いたので、ちょっと笑えました。。

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