- ベストアンサー
C++デバックエラーについての解説
- C++デバックエラーとは、Microsoft Visual C++ Debug Libraryで発生するエラーのことです。
- エラーメッセージには、変数'temp'が初期化されずに使用されているという内容が表示されます。
- 問題のあるコードの一部を紹介します。構造体E_SHOTの変数tempの初期化が行われていないため、予期せぬ動作が発生しています。
- みんなの回答 (13)
- 専門家の回答
質問者が選んだベストアンサー
現状の理解状態から推察するに…先は長そうですねぇ……。 >あとゴミが残っているとはどういう内容か知りたいです。 未初期化のローカル変数がどうなっているのか? ということを勉強してくださいな。 >データーはエクセルの一つのセルに1個ずつ CSV出力した時にどういう形式になっているのか理解しています? というか、出力したCSVをテキストエディタで眺めたことはありますか?? 読み込み処理の部分、デバッガのステップ実行で1つずつ追いかけて、 ・期待する動作はどんなものだったのか ・実際の動作はどうなのか を確認した方がいいでしょう。 http://marupeke296.com/DBG_No1_Step.html http://www.atmarkit.co.jp/fdotnet/chushin/vsdebug_01/vsdebug_01_02.html http://www.a.math.ryukoku.ac.jp/~hig/guide/vs2008/debugger.php http://visualstudiostudy.blog.fc2.com/blog-entry-9.html http://news.mynavi.jp/articles/2008/08/18/debug/ などなど……
その他の回答 (12)
- Tacosan
- ベストアンサー率23% (3656/15482)
本当にそのようなデータなのですか? データは, 本当に「1行に 1個ずつ書かれている」のですか? 自分のコードがどのようなデータを期待しているか, 理解できていますか?
お礼
お疲れ様です。 データーはエクセルの一つのセルに1個ずつ 書かれています。 自分のコードがどのようなデータを期待しているか, 理解できていますか? について 敵キャラ5匹分の 敵の種類、弾の種類、移動パターン、発射パターン、出現時間、停止、 発射、帰還、X座標、Y座標、弾スピード、HP、アイテムの値を 読み込み出力することです。 いつも丁寧にありがとございます。 失礼します。
- Wr5
- ベストアンサー率53% (2173/4061)
>全員が全員意図的に無視しているような感じがしてきた 意図的に無視していたわけでもなく、たいして気にしていなかった……。 が、まぁ、データ形式が微妙ですね。 # 掲示しているコードだと列と行が入れ替わっていることになりますし……。 意図した状態にデータを切り出せているのか…は自前で確認してもらいたいところ。 # なんか、だんだん当初の問題から離れていっているなぁ…。
お礼
いつもありがとございます。 まだ解決はしていないですがいろいろまとめながら 前に進み解決したいと思います。 失礼します。
- Tacosan
- ベストアンサー率23% (3656/15482)
全員が全員意図的に無視しているような感じがしてきたのですが, 読み込ませているデータは本当に ---------- ここから ---------- 敵の種類 0 0 0 0 0 弾の種類 0 0 0 0 0 移動パタターン0 0 0 0 0 発射パターン 0 0 0 0 0 出現時間60 120 180 240 300 停止 120 180 240 300 360 発射 121 181 241 301 361 帰還 300 340 400 460 520 X座標 50 100 150 200 250 Y座標 -40 -40 -40 -40 -40 弾のスピード 4 4 4 4 4 HP 1 1 1 1 1 アイテム 0 0 0 0 0 ---------- ここまで ---------- という形式なんですか? もしそうだとしたら, 途中にカンマが出てこないから 1行丸ごと読み込んじゃいますよ. つまり, type 以外には何も読み込まないから, stype にはゴミが残ったままです. データの形式が上の様ではないというなら, あなたが #3 への「お礼」に書いた「エクセル内容」は何の役にも立ちません. そんなクズを見せるのは「時間と労力の無駄」でしかないので, そんなことをするくらいなら (最初の数行でいいので) 実際のデータを出してください.
お礼
いつもありがとうございます。 形式の部分ですが実は 敵の種類 0 0 0 0 0 と1セルごとに中に記述してあります。(以下省略) この形式でもカンマは必要ですか。 あとゴミが残っているとはどういう内容か知りたいです。 いろいろ勉強不足ですいません。 また見かけたらよろしくお願いします。
- Wr5
- ベストアンサー率53% (2173/4061)
fgetc()で1文字ずつ読み込んで~とか処理しているから変に見えるんじゃないですかねぇ……。 Cランタイム使うならfgets()で1行まるっと読み込んで、CSVをパースする方がいいのではないかと。 # CSVをパースする処理自体はよくあるパターンなので、検索すればいろいろ見つかるでしょう。 # 「CSV C言語 読み込み」辺りで探せばそれなりに見つかるはずです。 # エラー処理簡略化するならstrtok()でぶった切ってもいいでしょうし。(strtok()でcsvを読み込む場合の問題点も検索すれば出てくるでしょうし) 読み込み処理自体もwhile(1)の無限ループとgotoでの脱出というのが違和感醸し出す元かと思われます。 >case 2: data[row].stype=atoi(buf); break; のところでdata[row].stypeが0以外の値になったらbufの内容を確認する。 みたいなコードを埋め込めば、とりあえずの原因は探せるかもしれません。 私なら…読み込み中のcsvファイルの行数をカウントするようにして、 case 2: data[row].stype=atoi(buf); if(data[row].stype != 0) { int a = 0; } break; でint a = 0;にブレークポイントを設定する…とかしますかね。 # TRACE()マクロとかOutputDebugString()を使うこともある。
お礼
いつもありがとございます。 まだ解決はしていないですがいろいろ検索しながら 他の方法も勉強しながら理解を深め解決したいと 思います。 また見かけたらよろしくお願いします。
- Picosoft
- ベストアンサー率70% (274/391)
> throw "Unknown stype\n"; でためさせてもらいました。 > そしたら以下のエラーが出てしまいました。 #4のコードは「stype==0じゃなかったらエラー発生とみなす」というコードです。 つまり、「エラーが出た」ということは「stype!=0になっているENEMYがいる」ということです。 (#7でも指摘されていますが) ファイルの読み込み部分を確認し、本当に意図通りに読み込めているかをチェックしてください。
お礼
いつもありがとうございます。 throw "Unknown stype\n"; については 勉強不足ですいません。 ファイルの読み込み部分でまだいきずまっていますが まとめながら進みたいと思います。 失礼します。
- Tacosan
- ベストアンサー率23% (3656/15482)
それはつまり stype == 0 を満たさないやつがいる ってことじゃないか? データをきちんと読み込めているかどうか, 確認した? あと #6 についていえば「単に 1文字ずつつなげる」だけなんだから strcat なんか使うことはない. 例えば char *buf_ptr; を用意し, memset のところを buf_ptr = buf; として strcat を呼び出す代わりに *buf_ptr++ = c; とする. そして, // ここにきたということは の次の switch の前で *buf_ptr = '\0'; とすればいい... あれ? なんか読み込み部分にすごい違和感がある....
お礼
いつもありがとうございます。 いろいろ勉強になります。 がんばります。 失礼します。
- Tacosan
- ベストアンサー率23% (3656/15482)
あ, 処理系が書いてあるのを見落としてた. バッファオーバーラン以外のバグはないな. ごめんなさい. とはいえ非常に不思議な書き方ではある. なぜに strcat?
お礼
Tacosanさん投稿していただきありがとうございます。 初心者な分知識が薄いためみなさんのいろんな言葉が 勉強になり気になることばかりでプログラムの好きな 自分にとってはたのしいことばかりです。 strcat?の理由もすごく気になります。知りたいです。 バッファオーバーランについても知識が薄いため 自分なりにも勉強して理解をするようにします。 みなさんのように回答できるようになりたいです。 失礼します。
- Tacosan
- ベストアンサー率23% (3656/15482)
本題ではありませんが.... #3 への「お礼」にあるプログラムにはバグが潜んでいます. 認識できていますか?
- Picosoft
- ベストアンサー率70% (274/391)
> 今の段階でstypeは0以外ありえないという意味です ということなら、今の段階では「stypeに0以外の数字が入っているのは想定外だからエラー」という風にしておけばいいのでは? //弾画像読み込み if(stype==0){ temp=LoadGraph("enemyshot1.png"); }else{ //stype!=0なのは想定外 throw "Unknown stype\n"; //例外にするなり、とりあえずstype==0のときと同様にして続行するなり、ご自由にどうぞ }
お礼
Picosoftさんお疲れ様です。 いつも感謝します。 throw "Unknown stype\n"; でためさせてもらいました。 そしたら以下のエラーが出てしまいました。 でも、throwやRuntime Error!についても理解が薄いので 勉強しながら頑張りたいと思います。 ありがとうございました。 失礼します。 Microsoft Visual C++ Runtime Library Runtime Error! Program: This application has requested the Runtime to terminate it in an unusual way Please contact the application's support team for more information. (たぶんこんな感じのことがかいてあるとおもうのですが) この適用は、異常な方法でそれを終了することをランタイムに要求しました。 詳細については適用のサポート・チームと連絡をとってください。
- Picosoft
- ベストアンサー率70% (274/391)
「今の段階では弾は一種類だけ」ということは「今の段階でstypeは0以外ありえない」という意味ですよね? どこかにstypeに0以外を指定しているENEMYはないですか?
お礼
Picosoftさんいつもありがとうございます。 今の段階でstypeは0以外ありえないという意味です stypeに0以外を指定しているENEMYについては switch文の部分でこのように指定している部分が case 2: data[row].stype=atoi(buf); break; だけです。 それでswitch文のコードの最後で敵クラスの生成をしています。 全体のコードでstypeに0以外を指定しているような部分は これだけです。 それでcontrol.cppですべてのクラスを操作しています 今回はcontrol.cppで 外部データ(エクセル)を読み込んで、 それを変数に入るようにしています。 それが下記にもあるこれです fp = fopen("enemydata.csv","r"); このエクセル内容が(敵キャラ五匹分です) 敵の種類 0 0 0 0 0 弾の種類 0 0 0 0 0 移動パタターン0 0 0 0 0 発射パターン 0 0 0 0 0 出現時間60 120 180 240 300 停止 120 180 240 300 360 発射 121 181 241 301 361 帰還 300 340 400 460 520 X座標 50 100 150 200 250 Y座標 -40 -40 -40 -40 -40 弾のスピード 4 4 4 4 4 HP 1 1 1 1 1 アイテム 0 0 0 0 0 です。 コードは control.cpp control.h enemy.h define.hは前回載せていなかった ENEMYDATAの部分をのせました。 前回と今回のでENEMY関係はこれで全部です。 失礼します。 (control.cpp) #include "pch.h" #include "control.h" #include <stdio.h> CONTROL::CONTROL() { player = new PLAYER; back = new BACK; FILE *fp; ENEMYDATA data[ENEMY_NUM]; char buf[100]; int c; int col=1; int row=0; memset(buf,0,sizeof(buf)); fp = fopen("enemydata.csv","r"); //ヘッダ読み飛ばし while(fgetc(fp)!='\n'); while(1){ while(1){ c=fgetc(fp); //末尾ならループを抜ける。 if(c==EOF) goto out; //カンマか改行でなければ、文字としてつなげる if(c!=','&& c!='\n') strcat(buf,(const char*)&c); //カンマか改行ならループ抜ける。 else break; } //ここにきたということは、1セル分の文字列が出来上がったということ switch(col){ //1列目は敵種類を表す。atoi関数で数値として代入。 case 1: data[row].type=atoi(buf); break; //2列目は弾種類。以降省略。 case 2: data[row].stype=atoi(buf); break; case 3: data[row].m_pattern=atoi(buf); break; case 4: data[row].s_pattern=atoi(buf); break; case 5: data[row].in_time=atoi(buf); break; case 6: data[row].stop_time=atoi(buf); break; case 7: data[row].shot_time=atoi(buf); break; case 8: data[row].out_time=atoi(buf); break; case 9: data[row].x=atoi(buf); break; case 10: data[row].y=atoi(buf); break; case 11: data[row].speed=atoi(buf); break; case 12: data[row].hp=atoi(buf); break; case 13: data[row].item=atoi(buf); break; } //バッファを初期化 memset(buf,0,sizeof(buf)); //列数を足す ++col; //もし読み込んだ文字が改行だったら列数を初期化して行数を増やす if(c=='\n'){ col=1; ++row; } } out: //敵クラス生成 for(int i=0;i<ENEMY_NUM;++i){ enemy[i]=new ENEMY( data[i].type, data[i].stype, data[i].m_pattern, data[i].s_pattern, data[i].in_time, data[i].stop_time, data[i].shot_time, data[i].out_time, data[i].x, data[i].y, data[i].speed, data[i].hp, data[i].item); } } void CONTROL::All() { //int count = 0; //描画領域を指定 SetDrawArea(MARGIN,MARGIN,MARGIN+380,MARGIN+460); back->All(); //プレイヤークラスのAll関数実行 player->All(); for(int i=0;i<ENEMY_NUM;++i){ if(enemy[i]!=NULL){ if(enemy[i]->All()){ delete enemy[i]; enemy[i]=NULL; } } } ++g_count; } CONTROL::~CONTROL() { //プレイヤークラスの解放 delete player; delete back; for(int i=0;i<ENEMY_NUM;++i){ if(enemy[i]!=0){ delete enemy[i]; } } } (control.h) #include "player.h" #include "back.h" #include "enemy.h" class CONTROL { private: double y; private: //プレイヤークラスのポインタ PLAYER *player; //背景クラス BACK *back; ENEMY *enemy[ENEMY_NUM]; public: CONTROL(); CONTROL(); void All(); }; (enemy.h) #include "pch.h" class ENEMY { private: //座標とグラフィックハンドル double x,y; int gh[3]; //画像サイズ int width,height; //出現、停止、帰還、発射タイミング int in_time,stop_time,out_time,shot_time; //敵の種類 int type; //弾の種類 int stype; //移動パターン int m_pattern; //ショットパターン int s_pattern; //弾スピード int speed; int hp; int item; //敵が出現してからのカウント int count; //敵消滅フラグ bool deadflag; //敵クラス消滅フラグ bool endflag; //弾の構造体 E_SHOT shot[ENEMY_SNUM]; //ショットが撃てるようになったかのフラグ bool sflag; //ショットが撃てるようになってからのカウント int scount; //関数関係 public: bool All(); void Move(); void Shot(); void Draw(); ENEMY( int type,//敵タイプ、 int stype,//弾種類 int m_pattern,//移動パターン、 int s_pattern,//発射パターン int in_time,//出現時間、 int stop_time,//停止時間、 int shot_time,//弾発射時間、 int out_time,//帰還時間、 int x,//x座標、 int y,//Y座標、 int speed,//弾スピード int hp,//HP int item//アイテム ); }; (define.h) struct ENEMYDATA{ int type;//敵種類 int stype;//弾種類 int m_pattern;//移動パターン int s_pattern;//発射パターン int in_time;//出現時間 int stop_time;//停止時間 int shot_time;//弾発射時間 int out_time;//帰還時間 int x;//x座標 int y;//y座標 int speed;//弾スピード int hp;//HP int item;//アイテム }; #define ENEMY_NUM 5//敵の数
- 1
- 2
お礼
お疲れ様です。 理解不足ですいません。 CSV出力した時にどういう形式になっているのか理解しています? いいえ 出力したCSVをテキストエディタで眺めたことはありますか?? いいえ サイトを確認しながら先が長くならないように努力します。 ありがとうございました。 失礼します。