Im 2行の列と可変nrの行からなるasciiファイルを読み込みます。読み取りはプロセッサ0によって行われ、データはMPI_Bcast(...)を使用して分散されます。データを含む1次元のバッファ配列を作成しなければならず、2次元を直接ブロードキャストする方法が見つからないため、他のすべてのprocsに送信されます。データ。 配列arrの割り当てに問題があります。データを印刷しようとすると、最初の3行が印刷され、次にセグメント化エラーが発生します。ほとんどの場合、いくつかの間違いがあります。Cでmpiを使用する関数で2d配列を割り当てて塗りつぶします
私はできるだけ単純な例を作ることを実際に試みました。 私のコード:
//global variables
...
double **testarray;
int dim;
...
int main(int argc, char **argv){
...
...
read_file("test.txt",&testarray,&dim);
}
int read_file(char* infilename,double ***arr,int *rowsout)
{
FILE* infile;
int i,j,ch,number_of_lines=0;
int rows=0;
//first count lines
if(myid==0) //myid is processor id
{
infile = fopen(infilename, "r");
do
{
ch = fgetc(infile);
if(ch == '\n')
number_of_lines++;
} while (ch != EOF);
if(ch != '\n' && number_of_lines != 0)
number_of_lines++;
//close file
fclose(infile);
rows=number_of_lines-1;
*rowsout=rows;
}
// every proc should know about length of file in order
//to be able to allocate memory
MPI_Bcast(rowsout,1,MPI_INT,0,MPI_COMM_WORLD);
//allocate memory
double *buf; //1D-buffer for 2D-array
MPI_Alloc_mem((*rowsout)*2*sizeof(double), MPI_INFO_NULL, &buf);
MPI_Alloc_mem((*rowsout)*sizeof(double*), MPI_INFO_NULL,arr);
for (i = 0; i < (*rowsout); i++) {
MPI_Alloc_mem(2*sizeof(double),MPI_INFO_NULL,&arr[i]);
}
// Now read file on proc 0
if(myid==0)
{
infile=fopen(infilename,"r");
for(i=0;i<rows;i++)
{
for(j=0;j<2;j++)
{
fscanf(infile,"%lf",arr[i][j]);
printf("arr[%d][%d]:%e\n",i,j,(*arr)[i][j]);
}
}
fclose(infile);
}
return 0;
//dont go further, error occurs before loop finishs
MPI_Bcast(buf,(rows)*2,MPI_DOUBLE,0,MPI_COMM_WORLD);
//now reconstruct array from buffer
for(i=0;i<(*rowsout);i++)
{
for(j=0;j<2;j++)
{
*arr[i][j]=buf[i*2+j];
}
}
MPI_Free_mem(buf);
return 0;
}
あなたは 'arr'を割り当てていますので、このMPIの内容は分かりませんが、通常の' malloc() 'では、' free() 'に一致する必要がありますすべての人)おそらく '(* arr)[i] 'ごとに自由にし、最後に' * arr'を解放する必要があります。また、C99以上を使用していない限り、C89/M $で実行されないことを知っていれば、 'main()'から 'return 0;'を明示的に指定する必要があります。デバッガでこれを実行しようとしましたか?また、 'rowsout'と' rows'の両方を持つ理由はないようですね。また、同じファイルを2回読んでいる場合は、それを閉じて再度開いてみてください。 – RastaJedi
'arr'を直接読んでいるのであれば、なぜ' buf'を持っているのか分かりません。また、あなたのループは最下位にあります(あなたの関数の早い段階で返ってきたので決して到達しないので、このループとフリーには決して到達しません)、おそらく '(* arr)[i] [j]' '* arr [i] [j]'。また、FYIだけで、 '(* rowsout)'の前後のかっこは必要ありません。また、 'do'ループは' ch'が 'EOF'に等しいときだけ終了するので、' '\ n'''と後で同じでないかどうかをテストするのは無意味で、 'number_of_lines'を1つだけ余分にして1を減算します'* rowsout'は無意味です。 – RastaJedi
そして '* rowsout'を直接使うことができるので、' number_of_lines'は本当に必要ありません。 – RastaJedi