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

解決済みの質問

C言語のプログラムなのですが、2点の座標(SとR)を指定して片方からも

C言語のプログラムなのですが、2点の座標(SとR)を指定して片方からもう片方への道筋を座標でcsvファイルに記述していくプログラムを作りたいのですが、うまく動きません。
参照渡しの所が間違っている様な気もするのですがわかりません。わかる方いましたらご指摘ください!

エラー内容:Segmentation Fault(core dumped)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

int Fugo(int);
void Flooding(int *,int *,int *,int *);

typedef struct{
int id;
int dX;
int dY;
}NodeStates;

NodeStates Node1[50];
NodeStates Node2[50];

int main(void)
{
int SX1,SY1;
int RX1,RY1;
int SX2,SY2;
int RX2,RY2;
int i=1;
int j=1;

FILE *fp;
fp=fopen("test.csv","w");

if(fp!=NULL){

printf("S1 Node PointX>>");
scanf("%d",&SX1);
printf("S1 Node PointY>>");
scanf("%d",&RX1);
printf("R1 Node PointY>>");
scanf("%d",&RY1);

Node1[0].id = 1;
Node1[0].dX = SX1;
Node1[0].dY = SY1;

printf("S2 Node PointX>>");
scanf("%d",&SX2);
printf("S2 Node PointY>>");
scanf("%d",&SY2);

printf("R2 Node PointX>>");
scanf("%d",&RX2);
printf("R2 Node PointY>>");
scanf("%d",&RY2);

Node2[0].id=1;
Node2[0].dX=SX2;
Node2[0].dY=SY2;

srand((unsigned int)time(NULL));

fprintf(fp,"First\n");
fprintf(fp,"NodeID,X,Y\n");
fprintf(fp,"%d,%d,%d\n",Node1[0].id, SX1, SY1);

while(!(SX1==RX1 && SY1==RY1)){
Flooding(&SX1, &SY1, &RX1, &RY1);
Node1[i].dX=SX1;
Node1[i].dY=SY1;
Node1[i].id=i+1;

fprintf(fp,"%d,%d,%d\n",Node1[i].id,Node1[i].dX,Node1[i].dY);
i++;
}

fprintf(fp,"Second\n");
fprintf(fp,"NodeID,X,Y\n");
fprintf(fp,"%d,%d,%d\n",Node2[0].id, SX2, SY2);

while(!(SX2==RX2 && SY2==RY2)){
Flooding(&SX2,&SY2,&RX2,&RY2);
Node2[j].dX=SX2;
Node2[j].dY=SY2;
Node2[j].id=j+1;

fprintf(fp,"%d,%d,%d\n",Node2[j].id,SX2,SY2);
j++;
}
}
fclose(fp);
return 0;
}

void Flooding(int *a,int *b,int *c,int *d){
int *e,*f,r;

*a=*a-*c;
*b=*b-*d;

*e=Fugo(*a);
*f=Fugo(*b);

*a=abs(*a);
*b=abs(*b);

r=rand()%3;
if(*a!=0&&*b!=0){
if(r==0){
*a=*a-1;
}
else if(r==1){
*a=*a-1;
*b=*b-1;
}
else *b=*b-1;
}
else if(*a==0)*b=*a-1;
else if(*b==0)*a=*b-1;

*a=*a**e+*c;
*b=*b**f+*d;
}

int Fugo(int a){
int n;

if(a>=0){
n=1;
}
else{
n=-1;
}
return n;
}

投稿日時 - 2010-10-08 15:30:21

QNo.6235934

すぐに回答ほしいです

質問者が選んだベストアンサー

結果を確認しましたか?
test.csvに途中まで出力されているはずです。

こちらでやったところ、最後は2つの座標をいったりきたりして、目的座標には永遠に到達しないようです。
そのため、Node1配列の最大添字を越えることが、エラーの直接の理由です。

真因は、Floodingのロジックの不具合です。
すでに指摘のあった、e,fをポインタからint型へ変更するのはもちろんなのですが。
・変数名がa,b,c....と、それぞれが何を意図したものかよくわからない。
・変更しないはずの目的座標までポインタで渡している。そのせいで *がいっぱいでよくわからない。
・出発座標を表わす (*a, *b )をいろいろ操作しすぎていて、ある行の*a,*bが何を表わすものなのかよくわからない
・*a,*bが何を表しているかよくわからないから、それを使って計算しているところも、それで式が正しいのかよくわからない
・よくわからないのに、コメントも無い
と、ロジックが正しいかどうか検証するのが非常に難しいプログラムになっています。
目的があってわざとやっているのでなければ、このあたりを直せばわかりやすいと思うのですが。

void Flooding(int *,int *,int ,int );
....
/* 添字はあとから変更/参照しやすいようにマクロにしておく */
#define MAX_NODE 50
NodeStates Node1[MAX_NODE]; /*グローバルに宣言する必要ありますか? */
....
while(!(SX1==RX1 && SY1==RY1)){
Flooding(&SX1, &SY1, RX1, RY1);
Node1[i].dX=SX1;
Node1[i].dY=SY1;
Node1[i].id=i+1;

fprintf(fp,"%d,%d,%d\n",Node1[i].id,Node1[i].dX,Node1[i].dY);
i++;
/* iがMAX_NODE以上になると、配列から溢れるので、エラーを出してループから抜ける*/
if ( i >= MAX_NODE ) {
/* エラー出力にエラーメッセージを出す */
fprintf(stderr,"%d以内に到着できません\n",MAX_NODE);
break ;
}
}
....
/* (x0,y0)から(x1,y1)へ向かう次の座標を x0,x1へ返す */
void Flooding(int *x0,int *y0,int x1,int y1){
int dx ,dy ; /* 目的座標からの差分 */
int a_dx ,a_dy ; /* 目的座標からの差分(絶対値) */
int s_dx ,s_dy ; /* 目的座標からの差分(方向,1/-1) */
int r ; /* 乱数 0-2 */

dx=*x0 - x1;
dy=*y0 - y1;

s_dx=Fugo(dx);
s_dy=Fugo(dy);

a_dx=abs(dx);
a_dy=abs(dy);

r=rand()%3;
if( a_dx !=0 && a_dy !=0 ){
if(r==0){
a_dx = a_dx - 1;
else if(r==1){
a_dx = a_dx - 1;
a_dy = a_dy -1;
} else a_dy = a_dy -1;
}
else if(a_dx==0) a_dy=a_dx-1; /* a_dx=0なのでかならずa_dy=-1になる */
else if(a_dy==0) a_dx=a_dy-1; /* a_dy=0なのでかならずa_dx=-1になる */
/* たぶん↑の2行のロジックがおかしい */

*a= a_dx * s_dx + x1;
*b= b_dy * s_dy + y1;
}

投稿日時 - 2010-10-08 19:17:27

お礼

回答していただきありがとうございます。

提示していただいた通り、関数の中を整理したらうまく動きました。
ご指摘の通り、変数やポインタで何を受渡して何を求めたいのかをまとめながら組んでいこうと思います。

お手数をおかけいたしました。
kmeeさまの回答をベストアンサーにさせていただきます。ありがとうございました。

投稿日時 - 2010-10-08 20:26:04

ANo.2

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

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

-広告-
-広告-

回答(2)

ANo.1

Wr5

>printf("S1 Node PointX>>");
>scanf("%d",&SX1);
>printf("S1 Node PointY>>");
>scanf("%d",&RX1);

SY1が不定な値になっていますが、問題ないのですか?
とんでもない値が入っていて、49ステップで届かないかも知れません。
# ステップの検証はしていませんが…
iの値の最大値を判定していませんので、Node1[10000].dXとか書き込もうとするかも知れません。
# jも同様。 もっともそんな値になる前に吹っ飛んでくれる可能性が高いです。

>int *e,*f,r;

eとfはint型を指すポインタです。
この時点ではどこを指しているのかは不定です。
>*e=Fugo(*a);
>*f=Fugo(*b);
ここまでででeとfには有効な(安全な)アドレスは設定されていません。
どこか不明の領域に書き込もうとしています。
よって…
>エラー内容:Segmentation Fault(core dumped)
で止められます。

投稿日時 - 2010-10-08 16:06:46

お礼

回答してくださりありがとうございます。
ご指摘の点ですがSY1については

printf("S1 Node PointX>>");
scanf("%d",&SX1);
printf("S1 Node PointY>>");
scanf("%d",&SY1);

としていました。記入漏れです、すみません。

iおよびjについては、Sの点がRの点と同一になった場合にループが止まるようにしたのですが、これではまずいということでしょうか?

>*e=Fugo(*a);
>*f=Fugo(*b);

この*e、*fをポインタではなく実数e、fで指定しても
Segmentation Fault(core dumped)
が出てしまします…。

お手数ですが、お分かりになりましたらご教授ください。

投稿日時 - 2010-10-08 16:38:07

-広告-
-広告-

あなたにオススメの質問

-広告-
-広告-