ページ 11

二次元配列に代入できない

Posted: 2007年7月18日(水) 17:40
by Bose
以前2次元配列を引数に持つような関数の作成方法を質問したものです.
動的メモリ確保の方法で無事コンパイルを通り安心していましたが,実行時にエラーがでてしまいました.
boxさんにアドバイスしていただいき,以下のプログラムとなりました.
#include <stdio.h>
#include <stdlib.h>

#define LEN (80)

typedef struct param {
	int param1;
	int param2;
} Param;

typedef struct kind {
	char filename[LEN];
	char message[LEN];
	Param param;
} Kind;

void mapFunction(Kind kind, double ***map);

int main(void)
{
	double **map[2];
	Kind kind[2] = {
		{ "TCOutputTorque.csv", "TCOutputTorque", { 15, 3 }, },
		{ "TCInputTorque.csv",  "TCInputTorque", { 18, 2 }, },
	};
	int i, j;
	
	mapFunction(kind[0], &map[0]);
	mapFunction(kind[1], &map[1]);

	for (i = 0; i < 2; i++) {
		for (j = 0; j < kind.param.param1; j++)
			free(map[j]);
		free(map);
	}
	return 0;
}

void mapFunction(Kind kind, double ***map)
{
	int i, j;
	double a;
	FILE *file;
	
	printf("%s\n", kind.message);
	file = fopen(kind.filename, "r");
	if (!file)
		fprintf(stderr, "open error\n"), exit(1);
	
	*map = (double **) malloc(sizeof(double *) * kind.param.param1);
	if (!*map){
		fprintf(stderr, "out of memory\n");
		exit(1);
	}
	for (i = 0; i < kind.param.param1; i++) {
		*map = (double *) malloc(sizeof(double) * kind.param.param2);
		if (!*map)
			fprintf(stderr, "out of memory\n"), exit(1);
		for (j = 0; j < kind.param.param2; j++) {
			fscanf(file, "%lf,", &a);
			*map[j] = a;/*ここでエラーが生じる*/
			map[j]=(double *)malloc(sizeof(double));
			fscanf(file, "%lf,", map[j]);
			printf("map[%d][%d] = %4.1f,", i, j, *map[j]);
		}
		printf("\n");
	}
	fclose(file);
}


自分なりにデバックしてみたところ,/*ここでエラー生じている*/のところでエラーが生じていました.
具体的には
*map[0][0]にaは代入できてる.
*map[0][1]にaが代入できずにエラーがでていることがわかりました.
しかしなぜjが1の時がだめなのかわかりません.
aは(j=1の時も)ファイルから読み込めています.

OSはWindowsXPでCygwinでgccコンパイルをしています.

原因がわかるようでしたら教えていただきたいです.宜しくお願いいたします.

Re:二次元配列に代入できない

Posted: 2007年7月18日(水) 17:44
by Bose
すみません.プログラムが間違っていました.
下記のプログラムが正しいです.
申し訳ありません.

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

#define LEN (80)

typedef struct param {
int param1;
int param2;
} Param;

typedef struct kind {
char filename[LEN];
char message[LEN];
Param param;
} Kind;

void mapFunction(Kind kind, double ***map);

int main(void)
{
double **map[2];
Kind kind[2] = {
{ "TCOutputTorque.csv", "TCOutputTorque", { 15, 3 }, },
{ "TCInputTorque.csv", "TCInputTorque", { 18, 2 }, },
};
int i, j;

mapFunction(kind[0], &map[0]);
mapFunction(kind[1], &map[1]);

for (i = 0; i < 2; i++) {
for (j = 0; j < kind.param.param1; j++)
free(map[j]);
free(map);
}
return 0;
}

void mapFunction(Kind kind, double ***map)
{
int i, j;
double a;
FILE *file;

printf("%s\n", kind.message);
file = fopen(kind.filename, "r");
if (!file)
fprintf(stderr, "open error\n"), exit(1);

*map = (double **) malloc(sizeof(double *) * kind.param.param1);
if (!*map){
fprintf(stderr, "out of memory\n");
exit(1);
}
for (i = 0; i < kind.param.param1; i++) {
*map = (double *) malloc(sizeof(double) * kind.param.param2);
if (!*map)
fprintf(stderr, "out of memory\n"), exit(1);
for (j = 0; j < kind.param.param2; j++) {
fscanf(file, "%lf,", &a);
*map[j] = a;/*ここでエラーが生じる*/
fscanf(file, "%lf,", map[j]);
printf("map[%d][%d] = %4.1f,", i, j, *map[j]);
}
printf("\n");
}
fclose(file);
}



自分なりにデバックしてみたところ,/*ここでエラー生じている*/のところでエラーが生じていました.
具体的には
*map[0][0]にaは代入できてる.
*map[0][1]にaが代入できずにエラーがでていることがわかりました.
しかしなぜjが1の時がだめなのかわかりません.
aは(j=1の時も)ファイルから読み込めています.

OSはWindowsXPでCygwinでgccコンパイルをしています.

原因がわかるようでしたら教えていただきたいです.宜しくお願いいたします

Re:二次元配列に代入できない

Posted: 2007年7月18日(水) 18:10
by box
差し支えなければ、入力ファイル(2つ)を提示していただけますか?

Re:二次元配列に代入できない

Posted: 2007年7月18日(水) 23:41
by Bose
入力ファイル1つ目です.
よろしくお願いいたします.

Re:二次元配列に代入できない

Posted: 2007年7月19日(木) 00:17
by Bose
ファイル名が変わってしまっていました.
先ほど添付した1つ目のファイルはTCOutputTorque.csvです.xls形式で開くと化けてしまいますので,csvファイルとして開いていただきたいです.

ここでは2つ目にTCInputTorque.csvを添付いたします.
よろしくお願いいたします.





Re:二次元配列に代入できない

Posted: 2007年7月19日(木) 20:27
by box
領域の動的確保について、私が考え違いをしていました。
修正したコードを載せますので、実行してみてください。
#include <stdio.h>
#include <stdlib.h>

#define LEN (80)

typedef struct param {
	int param1;
	int param2;
} Param;

typedef struct kind {
	char filename[LEN];
	char message[LEN];
	Param param;
} Kind;

void mapFunction(Kind kind, double ***map);

int main(void)
{
	double **map[2];
	Kind kind[2] = {
		{ "TCOutputTorque.csv", "トルコン領域マップ", { 15, 3 }, },
		{ "TCInputTorque.csv",  "エンジン特性マップ", { 18, 2 }, },
	};
	int i, j;

	mapFunction(kind[0], &map[0]);
	mapFunction(kind[1], &map[1]);

	for (i = 0; i < 2; i++) {
		for (j = 0; j < kind.param.param1; j++)
			free(map[j]);
		free(map);
	}
	return 0;
}

void mapFunction(Kind kind, double ***map)
{
	int i, j;
	FILE *file;

	printf("%s\n", kind.message);
	file = fopen(kind.filename, "r");
	if (!file)
		fprintf(stderr, "%s open error\n"), exit(1);
	
	for (i = 0; i < kind.param.param1; i++) {
		map = (double **) malloc(sizeof(double *) * kind.param.param1);
		if (!map)
			fprintf(stderr, "out of memory\n"), exit(1);
		
		for (j = 0; j < kind.param.param2; j++) {
			map[j] = (double *) malloc(sizeof(double) * kind.param.param2);
			if (!map[j])
				fprintf(stderr, "out of memory\n"), exit(1);
			fscanf(file, "%lf", map[j]);
			printf("map[%d][%d] = %4.1f,", i, j, *map[j]);
		}
		printf("\n");
	}
	fclose(file);
}

Re:二次元配列に代入できない

Posted: 2007年7月20日(金) 01:08
by Boze
無事実行できました.
boxさんありがとうございました!