我正在尝试读取一个 ascii 文件,该文件由 2 列和可变的 nr 行组成。读取由处理器 0 完成,然后使用 MPI_Bcast(...) 分发数据。我必须创建一个 1-dim 缓冲区数组,其中包含数据并发送到所有其他 proc,因为我还没有找到直接广播 2-dim 的方法。数据。 数组arr的分配有问题。当我尝试打印数据时,打印了前 3 行,然后出现段错误。很可能有几个错误。
我真的试图让这个例子尽可能简单。 我的代码:
//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 内容):
#include <stdio.h>
#include <stdlib.h>
void read_file(char *filename, double ***arr, int *rowsout);
int main(void)
{
double **testarray;
int dim;
read_file("test.txt", &testarray, &dim);
return 0;
}
void read_file(char *filename, double ***arr, int *rowsout)
{
FILE *infile;
int i, j, ch;
infile = fopen(filename, "r");
do
{
ch = fgetc(infile);
if (ch == '\n')
++*rowsout;
} while (ch != EOF);
rewind(infile);
*arr = malloc(sizeof **arr * *rowsout);
for (i = 0; i < *rowsout; ++i)
(*arr)[i] = malloc(sizeof ***arr * 2);
for (i = 0; i < *rowsout; ++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);
for (i = 0; i < *rowsout; ++i)
free((*arr)[i]);
free(*arr);
}
示例输入:test.txt
0.01 0.02
0.3 0.4
5.0 6.0
示例输出:
(*arr)[0][0]: 1.000000e-02
(*arr)[0][1]: 2.000000e-02
(*arr)[1][0]: 3.000000e-01
(*arr)[1][1]: 4.000000e-01
(*arr)[2][0]: 5.000000e+00
(*arr)[2][1]: 6.000000e+00
我认为错误来自于您的 fscanf()
行。当您使用 "%lf"
时,fscanf()
想要一个 double *
,但您传递的是 arr[i][ j]
这有两个问题:因为 arr
实际上是一个指向二维数组的指针,所以你需要先对它进行引用 ((*arr)
),其次,因为它需要 double
的地址,所以你需要使用 &
: &(*arr)[i][ j]
.
关于c - 在 C 中使用 mpi 在函数中分配和填充二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38902889/