こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

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;

}

}
になります。
ビルドの正常終了後になぜエラーがでるかと
内容を詳しく説明いただけるとありがたいです。
よろしくお願いします。

投稿日時 - 2014-01-23 05:34:09

QNo.8442497

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.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には必ず何かを入れること
}
という感じに直してみましょう。

投稿日時 - 2014-01-23 08:41:54

お礼

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

投稿日時 - 2014-02-03 19:04:34

ANo.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 の場合どうするべきか、は(プログラムの設計者である)あなたしか知らないのです。

投稿日時 - 2014-01-23 07:12:37

お礼

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

投稿日時 - 2014-02-03 19:36:56

ANo.3

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

駄目なことは分かるけど理由を間違えるってダメですねorz

投稿日時 - 2014-01-23 07:07:43

お礼

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

投稿日時 - 2014-02-03 20:09:41

ANo.2

コンストラクタ中の以下の部分

int temp;
//弾画像読み込み
if(stype==0){
temp=LoadGraph("enemyshot1.png");
}

//サイズ取得
int w,h;
GetGraphSize(temp,&w,&h);

で、stype が 0 ではないときは temp が初期化されません。

あと、ちょっとした小言になりますが、temp という変数名を使うのはやめましょう。もっとふさわしい変数名があるはずです。

投稿日時 - 2014-01-23 07:04:47

お礼

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

投稿日時 - 2014-02-03 19:50:52

ANo.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文で入らない場合おかしくなるとかは警告してくれません(設定でエラーチェックのレベルの設定で変更できたかも?)

投稿日時 - 2014-01-23 06:52:19