ページ 11

メモリの割り当て方について

Posted: 2018年2月04日(日) 19:19
by ctwb0583
プログラム(c言語)に関する質問です。
下記のプログラムが現在計算が止まってしまう状態です。(コンパイルはできる)
個人的には、関数(T)内で非常に大きな配列を確保しているから(スタックオーバーフロー?)だと考えています。
そこでメモリの割り当て方を、静的割り当てから動的割り当てに変更すれば解決するのではないかと考えているのですが、プログラミングについては素人なので現在勉強している途中です。しかし早急に解決しなければならない状態になってしまいました。誠に申し訳ないのですが具体的なプログラムを示していただけないでしょうか。お手数をおかけしますがよろしくお願いいたします。



#include <stdio.h>
#define M 129
#define N 106
#define T 1501
int main ()
{
int i, j, l, n;

double u[T][M][N], v[T][M][N];
double a[T][T], b[T][T];
double X[T][T];
char filename[T];


FILE *fp;
for(l=1; l<T; l++){
sprintf(filename, "U%d.txt", l);
fp = fopen(filename, "r");
printf("read U%d.txt\n",l);
for(i=1; i<M; i++){
for(j=1; j<N; j++){
fscanf(fp, "%lf%lf", &u[l][j], &v[l][j]);
}
}
}
fclose(fp);



for(n=1; n<T; n++){
for(l=1; l<T; l++){
for(i=1; i<M; i++){
for(j=1; j<N; j++){
a[n][l] += u[n][j]*u[l][j];
b[n][l] += v[n][j]*v[l][j];
}
}
}
}
printf("caliculated abc data\n");

for(i=1; i<T; i++){
for(j=1; j<T; j++){
X[j] = a[j] + b[j];
}
}
printf("caliculated X data\n");
FILE *fq;
fq = fopen("matrix.txt", "w");
for(i=1;i<T;i++){
for(j=1;j<T;j++){
fprintf(fq, "%15.15f,\n", X[j]);
}
}
fclose(fq);


return 0;
}

Re: メモリの割り当て方について

Posted: 2018年2月04日(日) 19:49
by ctwb0583
codeを囲っていませんでした。大変申し訳ありません。
何卒よろしくお願い致します。
個人的にはメモリを動的割り当てにするために、mallocを使用するのではないかと考えております。

コード:

#include <stdio.h>
#define M 129
#define N 106
#define T 1501
int main ()
{
	int i, j, l, n;
	
	double u[T][M][N], v[T][M][N];
	double a[T][T], b[T][T];
	double X[T][T];
	char filename[T];
	

	FILE *fp;
	for(l=1; l<T; l++){
		sprintf(filename, "U%d.txt", l);
		fp = fopen(filename, "r");
		printf("read U%d.txt\n",l);
			for(i=1; i<M; i++){
				for(j=1; j<N; j++){
					fscanf(fp, "%lf%lf", &u[l][i][j], &v[l][i][j]);
				}
			}
	}
	fclose(fp);



	for(n=1; n<T; n++){
		for(l=1; l<T; l++){
				for(i=1; i<M; i++){
					for(j=1; j<N; j++){
						a[n][l] += u[n][i][j]*u[l][i][j];
						b[n][l] += v[n][i][j]*v[l][i][j];
					}
				}
		}
	}
	printf("caliculated abc data\n");



	for(i=1; i<T; i++){
		for(j=1; j<T; j++){
			X[i][j] = a[i][j] + b[i][j];
		}
	}
	printf("caliculated X data\n");
	FILE *fq;
	fq = fopen("matrix.txt", "w");
	for(i=1;i<T;i++){
		for(j=1;j<T;j++){
			fprintf(fq, "%15.15f,\n", X[i][j]);
		}
	}
	fclose(fq);
	
	
	return 0;
}

Re: メモリの割り当て方について

Posted: 2018年2月04日(日) 19:56
by みけCAT
とりあえず、スタックに割り当てるメモリのサイズを増やすことでごまかすのではダメでしょうか?
Windowsでgccの場合、

コード:

-Wl,--stack,536870912
オプションでスタックサイズを指定することができます。
Linuxの場合、

コード:

ulimits -s unlimited
コマンドでスタックサイズを無制限にすることができます。

プログラムのスタックサイズを変更する - 忘れたときに備えた記録(2008-12-16)

ちなみに、このプログラムは未初期化の自動変数a, bの要素の値(不定)を34行目や35行目で計算に使っているので、未定義動作になりますね。

Re: メモリの割り当て方について

Posted: 2018年2月04日(日) 19:59
by かずま
ctwb0583 さんが書きました: 個人的にはメモリを動的割り当てにするために、mallocを使用するのではないかと考えております。
静的の方がいいと思います。
9~11行目の double の前に static を付けてください。
初期化も行われます。
26行目の fclose は、25行目の前に移して、fopen と対応させましょう。