C++とDXライブラリでゲームを作っているのですが、プログラム実行中にエラーが発生し、
強制終了する現象に悩まされています。
エラーの発生個所を追跡したところ、あるクラスがそのメンバ変数に保持した別のインスタンスのアドレスを、
プログラムの開始直後に見失っている事がわかりました。
問題のクラス類を簡単に示すと以下のようになります。
//----------------------------------------------------------------------------// //ヘッダファイル//////////////////////////////////////////////////////////////// const int TEISU_A = 16; //作るクラスAインスタンスの数 const int TEISU_B = 4; //作るクラスBインスタンスの数 class A{ private: //データ類 } class B{ private: A* mB_A; //クラスAインスタンスのアドレスを保持するポインタ //その他のデータ類 public: void SetA(A*); //mB_Aにアドレスの値を代入する関数 } class I{ //シングルトンクラス private: static I* mInstance; //自身を指すポインタ I(); ~I(); A* mI_A[TEISU_A]; //クラスAのアドレスを保持するポインタ B* mI_B[TEISU_A]; //クラスBのアドレスを保持するポインタ public: static void Create(); //シングルトン生成関数 static void Destroy(); //シングルトン破棄関数 static I* Instance(); //クラスIを利用するにはまずこれを呼ぶ必要がある //その他の処理関数 } //ソースファイル//////////////////////////////////////////////////////////////// //クラスAについての定義 A::A(){} A::~A(){} //クラスBについての定義 B::B(){ mB_A = 0; //設定しないままだとアクセスした瞬間落ちる } B::~B(){}; void B::SetA(A* a){ mB_A = a; } //クラスIについての定義 I::mInstance = 0; //これをしないとコンパイルが通らない I::I(){ for(int i=0; i<TEISU_B; i++){ //クラスBインスタンスを指定の数だけ生成 mI_B = new B(); } for(int i=0; i<TEISU_A; i++){ //クラスAインスタンスを指定の数だけ生成 mI_A = new A(); } //クラスAとクラスBの関連付け //クラスBのメンバ変数mB_AにクラスAインスタンスのアドレスを代入 mI_B[0]->SetA(mI_A[0]); mI_B[1]->SetA(mI_A[1]); mI_B[2]->SetA(mI_A[2]); mI_B[3]->SetA(mI_A[3]); } I::~I(){ for(int i=0; i<TEISU_B; i++){{ //クラスBインスタンスを破棄 delete mI_B; mI_B = 0; } for(int i=0; i<TEISU_A; i++){ //クラスAインスタンスを破棄 delete mI_A; mI_A = 0; } } void I::Create(){ mInstance = new I(); } void I::Destroy(){ mInstance->~I(); } I* I::Instance(){ if(mInstance==0){//初回アクセス時に始めてインスタンス生成 I::Create(); } return mInstance;/*****ここで問題発生*****/ } //以下その他の処理関数についての定義... //----------------------------------------------------------------------------//
クラスIはシングルトンです。
クラスIのコンストラクタが終了するときには全てのメンバ変数に何らかの値が入っています。
しかしメインループ内で最初にI::Instance()を呼び出した時,
I::mInstanceが返される瞬間にそのメンバ変数mI_A[0]だけがインスタンスを見失います。
(デバッグ時に変数を見ると,データ値が「???」になります。)
それ以外の,例えばI::mI_A[1]などには同様の現象は起こっていません。
また,I::mI_B[0]のクラスBインスタンスはそのメンバ変数B::mB_AにI::mI_A[0]と同じアドレスを格納しますが,こちらは見失っていません。よってI::mI_B[0]を通してのアクセスは可能です。
直接I::mI_A[0]にアクセスする処理を実行するとその瞬間に停止します。
そもそもなぜこのような設計になっているのかというと,プログラム中で自由にクラスBとクラスAの関連付けを変更できるようにしたかったからです。
またクラスIはプログラムの各所で呼び出される処理を担っているので,シングルトンとなっています。
なぜmI_A[0]だけがインスタンスを見失ってしまうのでしょうか。
また、どのようにすれば良いのでしょうか。
御指南のほどよろしくお願いします。
OS:WindowsXP SP3
開発環境:VC++EE2008,DXライブラリ
プログラミング歴:半年程度。趣味の範囲。