変数になぜかおかしな値が入ってしまいます

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

変数になぜかおかしな値が入ってしまいます

#1

投稿記事 by » 16年前

連日に投稿してすみません。
Visual Studio 2008 Express EditionとDXライブラリを使って、ゲーム(と呼べるレベルのものではまだありませんが)を作っています。
コンパイルはちゃんとできるのですが次のようなエラー?がでて、対処が分かりません。

Game2.exe の 0x004012e6 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0xc07fd410 を読み込み中にアクセス違反が発生しました。

エラーメッセージで検索もしてはみたのですが自分には書いてあることの意味が理解できませんでした。
エラーメッセージと同時に表示される情報を見ておかしいと思ったのが、char.ccpの

if(*(p_block+(ch.y/32+1)*20+(ch.x/32+1))==1 && ch.sky==1){

のあたり(直前?)でch.yになぜか-2147483296が代入されているらしいということなのですが、なぜそんな数が代入されてしまうのかが分からず、そもそもそれが原因であるかどうかも確信できません。
解決法を教えてください。


//main.ccp
#include "DxLib.h"
#include "Keys_Blocks.h"

void char_coord(int *Key,int *p_block);

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

//Loading pics
int back_i=0;
int ground=LoadGraph("Stones.png");

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない
//Back
LoadGraphScreen(-back_i,0,"virgo.jpg",FALSE);
if(back_i>1080-680)LoadGraphScreen(1080-back_i,0,"virgo.jpg",FALSE);
if(back_i>1080)back_i=0;
back_i++;

//Ground
int ground=LoadGraph("stones.png");
for(int i=0;i<20;i++){
for(int j=0;j<15;j++){
if(block[j]==1)DrawGraph(i*32,j*32,ground,TRUE);
}
}

//draw_char
char_coord(Key,p_block);

ScreenFlip();
}

DxLib_End();
return 0;
}

Re:変数になぜかおかしな値が入ってしまいます

#2

投稿記事 by » 16年前

//char.ccp
#include "DxLib.h"
#include <math.h>

#define g 6.6
#define y_max 2.0

typedef struct{
int x;
int y;
int img;
int direct;//right 1 or left 3
int inertia;
int j_flag;
int sky;
}cha;

cha ch={680/4,480-32*4,0,1,0,0,0};

void char_coord(int *Key,int *p_block){

int dora[12];
LoadDivGraph("char.png",12,3,4,24,32,dora);

int ex_y=ch.y;
int time1=0,time2=0;
double t;

//char_x
if(Key[KEY_INPUT_RIGHT]>0){
if(ch.sky==1)ch.x+=4;//accerate in the sky
ch.x+=3,ch.direct=1;//start walking
}
if(Key[KEY_INPUT_RIGHT]>10)ch.x+=4,ch.inertia=10;//start running and get inertia force
if(ch.direct==1 && Key[KEY_INPUT_RIGHT]==0 && ch.inertia==10)ch.inertia--;//inertia force is weakening
if(ch.direct==1 && ch.inertia<10 && ch.inertia>0)ch.x+=2,ch.inertia--;

if(Key[KEY_INPUT_LEFT]>0){
if(ch.sky==1)ch.x-=4;
ch.x-=3,ch.direct=3;
}
if(Key[KEY_INPUT_LEFT]>10)ch.x-=4,ch.inertia=10;
if(ch.direct==3 && Key[KEY_INPUT_LEFT]==0 && ch.inertia==10)ch.inertia--;
if(ch.direct==3 && ch.inertia<10 && ch.inertia>0)ch.x-=2,ch.inertia--;

//char_jump
if(Key[KEY_INPUT_UP]==1 && ch.j_flag<=2){
time1=GetNowCount();
ch.j_flag++; //up flag
ex_y=ch.y; //where it was
}

if(ch.j_flag!=0){
time2=GetNowCount();
t=(double)(time2-time1)/1000;
ch.y=ex_y-(int)((sqrt(2*g*y_max)*t-0.5*g*t*t)*(32*2)/y_max);//culc y
if((int)((sqrt(2*g*y_max)*t-0.5*g*t*t)*(32*2)/y_max)>0)ch.sky=1;

if(*(p_block+(ch.y/32+1)*20+(ch.x/32+1))==1 && ch.sky==1){
ch.y=(ch.y/32)*32;//discard fractions
ch.j_flag=0;
ch.sky=0;
}
}

ch.img=dora[((ch.x+ch.y)%12)/4+ch.direct*3];//choosing picture based on coordinates
if(ch.x>400){
ch.x=400;//cant move right anymore
ch.img=dora[(Key[KEY_INPUT_RIGHT]+Key[KEY_INPUT_UP])%3+3];//choosing picture based on KEY_INPUT_RIGHT time
}
DrawGraph(ch.x,ch.y,ch.img,TRUE);

}

//Keys_Blocks.h
int Key[256];

int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[/url]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key==1) GetHitKeyStateAll_InputKey++;
else GetHitKeyStateAll_InputKey=0;
}
return 0;
}

int block[15][20] = {
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};

int *p_block=(int *)block[0];





よろしくお願いします!

kazuoni

Re:変数になぜかおかしな値が入ってしまいます

#3

投稿記事 by kazuoni » 16年前

規約は読んでください。プレタグ、字下げで、解読しやすくしてください。

ちょっと内容訂正します^^;
*(p_block+(ch.y/32+1)*20+(ch.x/32+1))==1
で、
「(配列p_blockの先頭アドレス+整数)のアドレスのエイリアス==1なら」
っとなっていますが、(違ってたらごめんなさい。)
ch.x、ch.yの値によっては、p_blockの配列の確保している領域を超えて、
アクセスしていってしまっています。
ch.yはこのアクセスをする前までは正常のようです。
この不正アクセスによって、ch.yにも影響してしまっているので、
不適当な数値になっています。

もう一度、ch.x、ch.yの計算または今回の問題の条件を改善してみてください。

Re:変数になぜかおかしな値が入ってしまいます

#4

投稿記事 by » 16年前

>kazuoniさん

>規約は読んでください。プレタグ、字下げで、解読しやすくしてください。
すいません。

*(p_block+(ch.y/32+1)*20+(ch.x/32+1))==1
の直前に

if(ch.y/32+1>=0 && ch.y/32+1<15 && ch.x/32+1>=0 && ch.x/32+1<20)
を追加してみたところ起動まではできたのですが、このif文の次の行が全く実行されなくなってしまいました。
これはこの時点でch.yの値がおかしくなっているということでしょうか?
この行をはさむことで確保していない領域にアクセスすることはなくなると思ったのですがダメでした。

他にどのような点に注意して改善すればよいのか教えてください。

Re:変数になぜかおかしな値が入ってしまいます

#5

投稿記事 by » 16年前

//main.ccp 
#include "DxLib.h" 
#include "Keys_Blocks.h" 

void char_coord(int *Key,int *p_block); 

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ 
ChangeWindowMode(TRUE);//ウィンドウモード 
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化 

//Loading pics 
int back_i=0; 
int ground=LoadGraph("Stones.png"); 

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){ 
//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない 
//Back 
LoadGraphScreen(-back_i,0,"virgo.jpg",FALSE); 
if(back_i>1080-680)LoadGraphScreen(1080-back_i,0,"virgo.jpg",FALSE); 
if(back_i>1080)back_i=0; 
back_i++; 

//Ground 
int ground=LoadGraph("stones.png"); 
for(int i=0;i<20;i++){ 
for(int j=0;j<15;j++){ 
if(block[j]==1)DrawGraph(i*32,j*32,ground,TRUE); 
} 
} 

//draw_char 
char_coord(Key,p_block); 

ScreenFlip(); 
} 

DxLib_End(); 
return 0; 
}

Re:変数になぜかおかしな値が入ってしまいます

#6

投稿記事 by » 16年前

上はミスです。
コードを字下げして入れなおそうと思い、<pre>と</pre>を始めと終わりにつけたのですが、反映されないようです。
コード見難くてすいません。

kazuoni

Re:変数になぜかおかしな値が入ってしまいます

#7

投稿記事 by kazuoni » 16年前

またもやちらっとしか見ていないので適切かどうか分かりませんが・・・
もしかしたら、アクセス領域を超えているのではなくて、
オーバーフローを起こしているかもしれないです。
っというのも、time1は上キーか押された時はif文条件に合致し、
GetNowCount()の戻り値を代入しますが、
次のループはこの条件に合致しません。(Key[KEY_INPUT_UP]=0 or Key[KEY_INPUT_UP]=2になるため)
そして、フラグが立つので、次のループでは
if(ch.j_flag!=0)
に合致して、処理をします。
t=time2-time1としていますが、time1はローカル変数のため、実質は
t=time2-0
です。GetNowCount()はミリ秒単位なので、time2は結構大きな値だと思います。
その次に
ch.y=ex_y-(int)((sqrt(2*g*y_max)*t-0.5*g*t*t)*(32*2)/y_max)
ですが、t^2があるので、ここでオーバーフローを起こし、変な値が入っているのかもしれません。

一度、time1,time2を外部変数または静的変数にしてみてください。

Re:変数になぜかおかしな値が入ってしまいます

#8

投稿記事 by » 16年前

>kazuoni
time1、time2を静的関数にしたら警告など出ずに動きました!
画面の前で奇声を発するほどうれしいです!!
本当にありがとうございます!!


Ma

Re:変数になぜかおかしな値が入ってしまいます

#10

投稿記事 by Ma » 16年前

> <pre>と</pre>
半角を使ってください。

閉鎖

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