変数の値が急に勝手に変わる

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ハジ

変数の値が急に勝手に変わる

#1

投稿記事 by ハジ » 16年前

いつもお世話になっております。
このたびは「なんか知らないうちにとある変数が勝手に変わる」という現象を解決したくて描きこませていただきました。

具体的には、メインループの中でswitchを使用しているのですが
その判定に使用している変数(statusという名を使用しています)が
勝手に変わってしまいます。
具体的には"3"から3フレーム後"-65536"に変わります。

原因は不明なので、いたしかたなく無理やりdefault時に正常なstatusを代入していたのですが
今度は別の変数が変わってしまい、一時的な解決にもなりませんでした。

数字的にオーバーフロー?か何かとか思い調べてみたのですが
解決方法&似たような事例を見つけることができませんでした。

もしよろしければ解決法をご教授いただけると幸いです。

box

Re:変数の値が急に勝手に変わる

#2

投稿記事 by box » 16年前

> 具体的には、メインループの中でswitchを使用しているのですが
> その判定に使用している変数(statusという名を使用しています)が
> 勝手に変わってしまいます。
> 具体的には"3"から3フレーム後"-65536"に変わります。

現象だけ教えていただいても、どうにもならないです。
問題が発生している近辺のソースコードが見たいです。

ハジ

Re:変数の値が急に勝手に変わる

#3

投稿記事 by ハジ » 16年前

以下がメインループです。
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない

	switch(status)
	{
	case 0:
		Title();
		break;

	case 1: //メインゲーム

		counters();
		scroll();
		action();
		green_counter();
		gravity_up_down();
		gravity_change();
		drawing();
		game_resets();
		died();
		Gravity_draw();
		break;

	case 2:
		
		Life_counter();
		drawing();
		break;

	case 3:
		Stage_choice();	
		stage_make();
		break;

	default:
		DxLib_End();
		return 0;
		break;
	}

        ScreenFlip();
	}

    DxLib_End();
    return 0;
}
で、問題の現象が起こるcase 3にある関数は以下のものとなります
#include "DxLib.h"
#include "ExternGV.h"
#include "stage01_ex.h"
#include "stage02_ex.h"

void Stage_choice()
{
	for(i=0;i<2;i++)
	{
		DrawFormatString(550,350+(i+1)*50,white,"STAGE 0%d",i+1);
		DrawBox(500,350+stage_n*50,518,368+stage_n*50,white,true);
	}
	
	if((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_DOWN)  >= 1 && stage_n==1)
	{
		stage_n=2;
	}
	if((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_UP)  >= 1 && stage_n==2)
	{
		stage_n=1;
	}
	if((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_C ) >= 1)
	{
		switch(stage_n)
		{
		case 1:
			for(i=0;i<1024;i++)
			{		
				for(j=0;j<1024;j++)
				{
					make_block[j]=make01_block[j];
					stage_goal=stage_goal01;
				}
			}
			WaitTimer( 300 ) ;
			status=1;
			break;

		//case 2:	
		//	make_block[j]=make02_block[j];
		//	status=1;
		//	break;

		}
	}
}

--------------------------------------------------

#include "DxLib.h"
#include "ExternGV.h"


//ステージ情報より 1 のところにブロックを配置
void stage_make()
{
	for(i=0;i<1024;i++)
	{
		for(j=0;j<1024;j++)
		{
			if(make_block[j]==1)
			{
				x=j*bl.size;
				bl[bl_count].x=x;
				x=i*bl.size-7260;
				bl[bl_count].y=x;
				bl[bl_count].color=red;
				bl_count++;
			}
		}
	}
}


以上となります。

box

Re:変数の値が急に勝手に変わる

#4

投稿記事 by box » 16年前

Stage_choice() の中で、statusに1を代入している箇所があります。
そこを通った結果、メインループのswitch文で今度はcase 1:の箇所を通り、
そこの関数群を実行するうちにstatusの値がおかしくなっている、
というようなことはないですか? ないですよね…。

ハジ

Re:変数の値が急に勝手に変わる

#5

投稿記事 by ハジ » 16年前

というか、自分で載せておきながら上記の部分が直接関係していないと思っています。
なぜならばその個所を初回通過したときは問題なくて
ゲームをリセットした後で問題の現象が起こるからです…

なので、とりあえずcppファイルとhファイルをまとめたものを添付させていただきます。
上記の現象は
1.タイトルでENTERを押す
2.ステージ1を選ぶ(ENTER)
3.ゲーム中にリセット(R)
4.タイトルで再びENTERを押す
5.問題の現象が発生します。

以上となります。
詳細を記載しておらず大変申し訳ございませんでした。

dic

Re:変数の値が急に勝手に変わる

#6

投稿記事 by dic » 16年前

使用コンパイラは何でしょうか?
VC++6では変数の値が変更された時にブレークポイントで止まる機能があります
こういった機能を使われてはいかがでしょう?

たいちう

Re:変数の値が急に勝手に変わる

#7

投稿記事 by たいちう » 16年前

デバッグしてくれというのは勘弁。私は。
↓のようなことが起こっていると思うけど。
int main()
{
	int before[2];
	int x;
	int after[2];
	
	printf("%x\n", before);
	printf("%x\n", &x);
	printf("%x\n", after);

	x = 666;
	printf("x = %d\n", x);

	before[0] = 100;
	before[1] = 101;
	before[2] = 102;
	before[3] = 103;
	before[4] = 104;

	printf("x = %d\n", x);

	after[0] = 200;
	after[1] = 201;
	after[2] = 202;
	after[3] = 203;
	after[4] = 204;

	printf("x = %d\n", x);

	return 0;
}

nayo

Re:変数の値が急に勝手に変わる

#8

投稿記事 by nayo » 16年前

ないとは思いますがリリースモードでデバッグしたりとかそんなことはないでしょうか

dic

Re:変数の値が急に勝手に変わる

#9

投稿記事 by dic » 16年前

ソースをコンパイルさせてもらいましたが
>具体的には"3"から3フレーム後"-65536"に変わります
というような現象は起きませんでした

pooka

Re:変数の値が急に勝手に変わる

#10

投稿記事 by pooka » 16年前

デバッグしてみたところ確かに問題の現象が起こりました。
その時stage_make関数のi=75,j=17あたりで、blという構造体の配列?に対して
たいちうさんが書かれているようなことをしているようです。

conio

Re:変数の値が急に勝手に変わる

#11

投稿記事 by conio » 16年前

範囲外のものを書き換えたりしているのではないでしょうか。

パッと見たところstatusには
-----------------------
status = 0;
status = 1;
status = 2;
status = 3;
-----------------------
みたいな記述しかないので、おかしな値が入る事は無いと思います。

考えられるのは下記のように、変な所へ値を入れたりしているのではないかと。
(上記でも指摘がありましたが)
-------------
int temp[5];
temp[7] = 10;
-------------

あと、バグとは別にexternが多いかもしれません。
至る所でexternがあるため、どこのファイルのどの関数(変数)なのか分かりづらくなっているように
思いました。

ハジ

Re:変数の値が急に勝手に変わる

#12

投稿記事 by ハジ » 16年前

お世話になっております。

とりあえずpookaさんやたいちうさんがおっしゃっている内容が問題っぽいです…

>-------------
>int temp[5];
>temp[7] = 10;
>-------------

ちなみにこれと似ている行為として

int temp[10];
temp[/url]={0,1,2,3}
みたいなことをやっております。
なんでこんなことをやっているのかといいますと

temp[/url]={ここの部分}

「ここの部分」の個数(要素?)が状況によって異なるので
とりあえずint temp[100];としておけばオッケーでしょって感じで作業を進めていました。

やっぱりこれは駄目なのでしょうか?
またダメだとすればどのように対処すればよろしいでしょうか?
(sizeof関数?)

※あとたいちうさんやpookaさんのプログラムがなぜエラーになるかわかんなかったりします。なぜそうなるのでしょうか?

ハジ

Re:変数の値が急に勝手に変わる

#13

投稿記事 by ハジ » 16年前

すみません。pookaさんではなくconioさんでした。

pooka

Re:変数の値が急に勝手に変わる

#14

投稿記事 by pooka » 16年前

make_blockという配列をinitialzation関数の中で0で初期化したところ一応大丈夫のようです。

リセットしてもmake_blockという配列に前のデータが残っていて、
stage_make関数のif(make_block[j]==1)の条件を満たして、bl_countの値が増えていき、
配列の範囲外にアクセスしたのだと思います。

conio

Re:変数の値が急に勝手に変わる

#15

投稿記事 by conio » 16年前

>>※あとたいちうさんやpookaさんのプログラムがなぜエラーになるかわかんなかったりします。なぜそうなるのでしょうか?
まず、変数などはメモリに割り当てられますよね。

例えば、下記のように3×3の二次元配列を定義します。
----------------------------------------------------
	int temp[3][3] = {0};

	temp[0][2] = 1;  //値を1に変える

	for(int i = 0; i < 3; i++)
	{
		for(int j = 0; j < 3; j++)
		{
			if(temp[j] == 0)
				printf("○");
			else if(temp[j] == 1)
				printf("●");
		}
		puts(" ");
	}
----------------------------------------------------

この場合、メモリ上は下記のように並んでます。
で、途中でtemp[0][2]の値を1に書き換えてます。
----------
┃[0][0]
┃[0][1]
┃[0][2]←1にする
┃[1][0]
┃[1][1]
┃[1][2]
┃[2][0]
┃[2][1]
▼[2][2]
----------
プログラムを実行すると
○○●
○○○
○○○
となります。

では、"temp[0][5] = 1;"にするとどうなるかというと、エラーにはなりません。
実行結果は
○○○
○○●
○○○
となります。この結果から見ても分かるように、メモリ上は下記のようになっているため、
"temp[0][5]とtemp[1][2]は同じ場所を示す"状態になります。
よって、直接いじっていないtemp[1][2]の値が書き換えられてしまった訳です。

----------
┃[0][0]
┃[0][1]
┃[0][2]
┃[1][0]
┃[1][1]
┃[1][2] == [0][5]
┃[2][0]
┃[2][1]
▼[2][2]
----------

上記の例は2次元配列に収まっていました。が、もし収まらなかった場合(temp[2][3] = 1など)
どうなるかと言うと、全く関係ない場所が書き換えられてしまいます。

そこに運悪くstatusがあった場合は、statusの値が変わってしまいます。
(実際は変数の型によって色々と大きさが違うため、訳のわからない値になるかと)
----------
┃[0][0]
┃[0][1]
┃[0][2]
┃[1][0]
┃[1][1]
┃[1][2]
┃[2][0]
┃[2][1]
▼[2][2]
 status = 1
----------

ハジ

Re:変数の値が急に勝手に変わる

#16

投稿記事 by ハジ » 16年前

>pookaさん
解決しました!ありがとうございます。

>リセットしてもmake_blockという配列に前のデータが残っていて、
>stage_make関数のif(make_block[j]==1)の条件を満たして、bl_countの値が増えていき、
>配列の範囲外にアクセスしたのだと思います。
bl[1024]がオーバーすることによるエラーなのだということはわかりましたが
なぜbl_countがオーバーしたのでしょうか?bl_countは初期化していたのに…
すみません。知識不足で…

>conioさん
わかりやすい解説誠にありがとうございます!
いわゆるメモリのアドレスの話(?)でしたか…
個人的にはプログラムを始めたばかりなのですが
今回初めてポインタの意味を感じました。
(ポインタを使っていれば、何でエラーがでたかすぐにわかるのですね…)


みなさま深夜までご対応誠にありがとうございました!
これにて解決とさせていただきます!

閉鎖

“C言語何でも質問掲示板” へ戻る