• 締切済み

C++デバックエラーについて詳しく教えてください。

Picosoftさんまだ未熟で解消できませんでした。 また見てたらお願いします。 他の人もお願いします。 Microsoft Visual C++ Debug Library と言うエラーが発生しました。 Visual C++ 2008 Express Edition を使っています。 状況は以下になります。 Program:C:\DxLib_VC\サンプルプログラム実行用フォルダ \Debug\DxLib_VC2008用.exe Module:C:\DxLib_VC\サンプルプログラム実行用フォルダ \Debug\DxLib_VC2008用.exe File: Run-Time Check Failure #3 - The variable 'temp' is being used without being initialized (Press Retry to debug the application) Run-Timeの部分から自分なりに調べてみたのですが ランタイム・チェック失敗#3-変数'temp'は初期化されずに使用されています と書いてあると思うのですが、tempの部分のコードは以下です。 (define.h) struct E_SHOT{ bool flag;//弾が発射中かどうか double x;//x座標 double y;//y座標 int gh;//グラフィックハンドル int width,height;//画像の幅と高さ int pattern;//ショットパターン int speed;//弾スピード }; #define ENEMY_SNUM 50//敵の弾の上限 (enemy.cpp) #include "pch.h" #include "enemy.h" ENEMY::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//アイテム) { //サイズ width=27; height=25;      //敵の種類 this->type=type; //弾の種類 this->stype=stype; //移動パターンとショットパターン this->m_pattern=m_pattern; this->s_pattern=s_pattern;      this->speed=speed; //座標セット this->x=x; this->y=y; //出現、停止、発射、帰還セット this->in_time=in_time; this->stop_time=stop_time; this->shot_time=shot_time; this->out_time=out_time; //hpとアイテム代入 this->hp=hp; this->item=item; //弾初期化 memset(shot,0,sizeof(shot)); //敵画像読み込み if(type==0){ LoadDivGraph("enemy.png",3,1,3,27,25,gh); } int temp; //弾画像読み込み if(stype==0){ temp=LoadGraph("enemyshot1.png"); } //サイズ取得 int w,h; GetGraphSize(temp,&w,&h); //弾の初期化 for(int i=0;i<ENEMY_SNUM;++i){ shot[i].flag=false; shot[i].gh=temp; shot[i].width=w; shot[i].height=h; shot[i].pattern=s_pattern; shot[i].speed=speed; shot[i].x=x; shot[i].y=y; } count=0; scount=0; deadflag=false; endflag=false; sflag=false; } void ENEMY::Move() { //出てきてから止まる時間までの間なら下に移動 if(in_time<g_count && g_count<stop_time){   y+=2;      //帰還時間を過ぎたら戻る。 }else if(g_count>out_time){    y-=2;    if(y<-40){    deadflag=true;  }    } } void ENEMY::Draw() { int temp; //弾から最初に描画 for(int i=0;i<ENEMY_SNUM;++i){ if(shot[i].flag){ DrawGraph(shot[i].x,shot[i].y,shot[i].gh,true); } } if(!deadflag){ temp= count%40/10; if(temp==3) temp=1; DrawGraph(x,y,gh[temp],TRUE); } } bool ENEMY::All() { Move(); Shot(); Draw(); ++count; return endflag; } void ENEMY::Shot() { //発射タイミングになったら、フラグを立てる if(shot_time==g_count){    sflag=true;    } //フラグを立てるときだけ if(sflag){   switch(s_pattern){ case 0: //10回に一回発射。40までなので5発発射。 if(scount%10==0 && scount<=40){ for(int i=0;i<ENEMY_SNUM;++i){ //フラグが立ってない弾を探して、座標をセット if(shot[i].flag==false){   shot[i].flag=true; shot[i].x=x; shot[i].y=y; break; } } } break; } //フラグが立ってる弾の数 int s=0; //フラグが立ってる弾だけ、弾の移動を行う for(int i=0;i<ENEMY_SNUM;++i){ if(shot[i].flag){ shot[i].y+=shot[i].speed; //弾が画面をはみ出たらフラグを戻す。 if(shot[i].x<-20 || shot[i].x>420 || shot[i].y<-20 || shot[i].y>500){ shot[i].flag=false; continue; } ++s; } } //sがゼロということは発射中の弾がない。 //かつdeadflagがTRUEということはこの敵のクラスは消滅させてよい if(s==0 && deadflag){ //敵クラス消滅フラグをTRUEにする endflag=true; } ++scount; } } になります。 ビルドの正常終了後になぜエラーがでるかと 内容を詳しく説明いただけるとありがたいです。 よろしくお願いします。

みんなの回答

  • Picosoft
  • ベストアンサー率70% (274/391)
回答No.5

前の質問らしきものを貼っておきますー。(なぜか別IDですが) http://okwave.jp/qa/q8436433.html 前回のご質問でも指摘しましたし、他の方も指摘してくださっていますが、 stype!=0のときのtempの値が不定です。 なので、 if(stype==0){  temp=LoadGraph("enemyshot1.png"); //←stype==0のときしかtempが初期化されない }else{  //TODO: stype!=0のときの処理を書く  //この中で、tempには必ず何かを入れること } という感じに直してみましょう。

bari-kinki
質問者

お礼

Picosoftさんいつもありがとうございます。 ちがうIDは情報を忘れログインできなくなり変更していました。 教えてもらったstype!=0のときの処理が書けません。 でも考え、調べて気ずいたことをまとめながら今も勉強しています。 それでtempに何か入れると初期化はされるのですが、 複数の敵が出てきて弾を撃ってくるはずが 敵事態でてこなくなり プレイヤーだけしかでなくなりました。 でもいつも時間を使って意見くださることに感謝します。 投稿の日にちが古くなったので新しくしたいと思います。 みかけたらよろしくお願いします。 失礼します。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

int temp;        ← ここで宣言したtemp を //弾画像読み込み if(stype==0){ temp=LoadGraph("enemyshot1.png");  ← ここで代入して } //サイズ取得 int w,h; GetGraphSize(temp,&w,&h);  ← ここで使っています ですが、 stype == 0 が偽のとき(stype != 0 のとき) 、 temp = .... は実行されません。 その場合、実行されるのは int temp;        ← ここで宣言したtemp を GetGraphSize(temp,&w,&h);  ← ここで使っています となります。 C++言語では、このように宣言された変数は、初期化されません。 他言語のように「初期値が0」とかにはならないのです。 この状態で、tempの中身が何であるかは決まっていません。 0かもしれないし -9876 かもしれません。 ということは GetGraphSize(-9876,&w,&h); と実行するかもしれない、ということです。 ※ より正確なことは「自動変数 宣言 初期化」あたりで検索してください。 コンパイルで見るのは、「文法が正しいかどうか」であって、「機能が正しいかどうか」ではありません。 「ビルドが正常終了する」したからといって「プログラムとして正しい」とは言えません。 今のプログラムは「C++言語の文法」としては間違いではありません。 そのため、ビルドは正常終了します。 ※ 警告レベルを高くしておくと、警告メッセージが出たはずです。 ※ 警告はエラーではない(設定でエラーにもできますが)ので、警告が出ても正常終了になります。 リリースビルドでは、おかしな数値のまま実行します。 その結果、期待しない挙動をして、時にはエラーで終了するかもしれませんが、正常に動作する(ように見える)こともあります。 デバグビルドでは、本来はやらないような監視をしています。 実際にtempに値が設定されないまま、GetGraphSizeで値を参照しようとしたため、「エラー」が発生したものです。 ※ GetGraphSize側で、異常な数値が来ても対応できているから、エラーにしてもらっては困る、と言われても、コンピュータにはその判断ができません。 対処法は、残念ですが、あなたが考えるしかありません。 stype != 0 の場合どうするべきか、は(プログラムの設計者である)あなたしか知らないのです。

bari-kinki
質問者

お礼

kmeeさんお疲れ様です。 今も解決出来なく勉強しています。 それでtempを初期化するようにしたら 敵キャラが複数出てきて弾を撃つはずが 敵キャラ事態でなくなり プレイヤーしかでなくなりました。 でも詳しい意見に理解を深める部分があり とても感謝しています。 日付けが古くなったので新しくしようと思います。 見かけたらよろしくお願いします。 それでは失礼します。

回答No.3

No.1です。 普通に間違えました。 /* tempが作成、この時点ではtempの中身はなし(NULL)*/ とありますが、NULLではなく何が入っているか分からないが正しいです。 NULLは0を表す定義なので0ですね(自信なし) 変数を宣言した場合そのままでは使えないので、初期化するか値を代入してください。 プログラムでは初期化されてませんでしたし、if文で入らない場合がるのに使用しているから駄目と言うことです(GetGraphSize(temp,&w,&h)でtempを関数に渡そうとして失敗している?) 他のtempや変数も直してくださいね。 駄目なことは分かるけど理由を間違えるってダメですねorz

bari-kinki
質問者

お礼

piraticalmanさんお疲れ様です。 今も解決できなく勉強しています。 初期化するようにしたのですが 複数の敵が出てきて弾を撃つはずが 敵事態でてこなくなり プレイヤーしか出てこなくなりました。 でも時間を作って意見していただき感謝します。 それで日付けが古くなったので新しくします。 またよろしくお願いします。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.2

コンストラクタ中の以下の部分 int temp; //弾画像読み込み if(stype==0){ temp=LoadGraph("enemyshot1.png"); } //サイズ取得 int w,h; GetGraphSize(temp,&w,&h); で、stype が 0 ではないときは temp が初期化されません。 あと、ちょっとした小言になりますが、temp という変数名を使うのはやめましょう。もっとふさわしい変数名があるはずです。

bari-kinki
質問者

お礼

hitomuraさんお疲れ様です。 tempを初期化するようにしたら 複数の敵が出てきて弾を撃つはずが 敵事態でてこなくなり プレイヤーだけしか出なくなり 今も勉強中です。 変数名にも気をつけます。 日付けが古くなったので新しくします。 また見かけたらよろしくお願いします。

回答No.1

多分ですが ランタイム・チェック失敗#3-変数'temp'は初期化されずに使用されています この意味のままだと思います 意味の説明するとtempに値が入っていないのに使用してますということです。 なのでtempに必ず値を入れるようにすれば良いだけです。 プログラムを一部コピーしました。 これを使って説明しますね。 /**/で囲んだのが私の解説です /* tempが作成、この時点ではtempの中身はなし(NULL)*/ int temp; //弾画像読み込み if(stype==0){ /*stypeが0の場合画像を読み込む*/ temp=LoadGraph("enemyshot1.png"); } /*stypeが0以外の場合画像を読み込んでない!tempがNULL!*/ //サイズ取得 int w,h; /*stypeがNULLの可能性がある!*/ GetGraphSize(temp,&w,&h);/*tempがNULLの場合何もないNULLを使用してるのでエラー*/ と言う感じおかしいです。 ビルドの正常終了後にエラーについてですが、プログラム実行時のエラーですよね。 ビルドでは文法的におかしくないかとか簡単にしか見ないのでif文で入らない場合おかしくなるとかは警告してくれません(設定でエラーチェックのレベルの設定で変更できたかも?)