MPI_scatter:缓冲区指针无效
MPI_scatter: Invalid buffer pointer
有人能说出我做错了什么吗。代码:
#include<stdio.h>
#include<mpi.h>
void transpose(int ** p, int row, int col)
{
int ** tempVar;
tempVar = (int *)malloc(sizeof(int *)* row);
int i = 0;
for (; i < row; i++)
{
tempVar[i] = (int *)malloc(sizeof (int *)* col);
int j = 0;
while (j < col)
{
tempVar[i][j] = p[j][i];
j++;
}
}
p = tempVar;
}
void main(int argc, char * argv[])
{
int rank, size;
MPI_Init(argc, argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int d[] = { 1000, 1000, 1000, 1000, 1000, 1000 };
int vt[6] = { 1000, 1000, 1000, 1000, 1000, 1000 };
int ** p;
p = (int *)malloc(sizeof(int *)* 6);
int i = 0;
int row = 6;
int col = 6;
while (i < 6)
{
p[i] = (int *)malloc(sizeof(int *)* 6);
/*int j = 0;
if (rank == 0)
{
while (j < 6)
{
scanf("%d", p[i][j]);
j++;
}
}*/
i++;
}
p[0][0] = 0; p[0][1] =2 ; p[0][2] =3 ; p[0][3] =1 ; p[0][4] =1000 ; p[0][5] =1000 ;
p[1][0] = 2; p[1][1] = 0; p[1][2] = 1000; p[1][3] = 1000; p[1][4] = 5; p[1][5] = 1000;
p[2][0] = 3; p[2][1] = 1000; p[2][2] = 0; p[2][3] = 1000; p[2][4] = 1000; p[2][5] = 1;
p[3][0] = 1; p[3][1] = 1000; p[3][2] = 1000; p[3][3] = 0; p[3][4] = 4; p[3][5] = 3;
p[4][0] = 1000; p[4][1] = 5; p[4][2] = 1000; p[4][3] = 4; p[4][4] = 0; p[4][5] = 2;
p[5][0] = 1000; p[5][1] = 1000; p[5][2] = 1; p[5][3] = 3; p[5][4] = 2; p[5][5] = 0;
int smallest;
if (rank == 0)
{
//transpose(&p , row , col);
smallest = 0;
vt[smallest] = smallest;
//MPI_Bcast();
}
int vt1, d1;
vt1 = d1 = 0;
int roww[6];
MPI_Scatter(vt, 6, MPI_INT, vt1, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(d, 6, MPI_INT, d1, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(p, row *row, MPI_INT,roww, 6, MPI_INT, 0, MPI_COMM_WORLD);
i = 0;
while (i < (row*row)/size)
{
MPI_Bcast(smallest, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (vt1 != rank)
{
if (roww[smallest] != 1000)
{
if (d1 > roww[smallest])
d1 = roww[smallest];
}
}
MPI_Gather(d1, 1, MPI_INT, d, row, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
{
smallest = d[0];
int k = 1;
int index = 0;
while (k < 6)
{
if (d[k] < smallest)
{
smallest = d[k];
index = k;
}
k++;
}
vt[k] = index;
}
MPI_Scatter(vt, 6, MPI_INT, vt1, (row) / size, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(d, 6, MPI_INT, d1, (row) / size, MPI_INT, 0, MPI_COMM_WORLD);
i++;
}
MPI_Finalize();
}
我得到的错误是
致命错误:MPI_Scatter中出现致命错误:缓冲区指针无效,错误堆栈:
MPI_Scatter(760):MPI_Scatter(sbuf=0x085f7ac,scount,MPI_INT,rbuf=0x000000,rcount=1,MPI_INT,root=0,MPI_COMM_WORLD)失败
您提供的代码编译时带有许多不可忽略的警告,例如:
passing argument 2 of ‘MPI_Init’ from incompatible pointer type
仔细观察函数的原型:如果调用类似int d;fun(d);
的东西,int* fun(int* b);
可能会失败。如果函数需要一个指向数据的指针,fun(&d)
可能会更好地工作。当调用MPI函数时,这个问题会发生很多次。
更多:函数transpose(int ** p)
试图通过执行p= tempVar
来修改p
。正如@WhozCraig发出的信号,通过执行int **p;...;transpose(p,...)
,函数transpose()
范围内的p的副本被修改,但不修改p
。因此,这个函数的正确原型是transpose(int ***p,...)
,调用它的正确方法是int** p;...;transpose(&p,...);
关于内存分配:您找到了一种分配2D数组的方法!但是数据在内存中不是连续的,因为一次只分配一行。如果您计划使用MPI函数(如MPI_Scatter()
),那么分配一个连续的2D数组是正确的做法(更多)。
附加建议:在正确的时间调用free()
以释放内存并避免内存泄漏。不投射malloc()
的返回
下面是一段应该使用mpicc main.c -o main -Wall
进行良好编译的代码。选项-Wall
启用所有警告。它似乎运行得很好,尽管我没有检查结果是否正确。
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
void transpose(int *** p, int row, int col)
{
int ** tempVar;
tempVar = malloc(sizeof(int *)* row);
if (tempVar==NULL){printf("malloc failedn"); exit (1);}
tempVar[0] = malloc(sizeof (int )* col*row);
if (tempVar[0]==NULL){printf("malloc failedn"); exit (1);}
int i = 0;
for (i=0; i < row; i++)
{
tempVar[i] = &tempVar[0][col*i];
int j = 0;
while (j < col)
{
tempVar[i][j] = (*p)[j][i];
j++;
}
}
free((*p)[0]);
free(*p);
*p = tempVar;
}
int main(int argc, char * argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int d[] = { 1000, 1000, 1000, 1000, 1000, 1000 };
int vt[6] = { 1000, 1000, 1000, 1000, 1000, 1000 };
int ** p;
int i = 0;
int row = 6;
int col = 6;
p = malloc(sizeof(int *)* row);
if (p==NULL){printf("malloc failedn"); exit (1);}
p[0] = malloc(sizeof(int )* row*col);
if (p[0]==NULL) {printf("malloc failedn"); exit (1);}
while (i < row)
{
p[i] = &p[0][i*col];
/*int j = 0;
if (rank == 0)
{
while (j < 6)
{
scanf("%d", p[i][j]);
j++;
}
}*/
i++;
}
p[0][0] = 0; p[0][1] =2 ; p[0][2] =3 ; p[0][3] =1 ; p[0][4] =1000 ; p[0][5] =1000 ;
p[1][0] = 2; p[1][1] = 0; p[1][2] = 1000; p[1][3] = 1000; p[1][4] = 5; p[1][5] = 1000;
p[2][0] = 3; p[2][1] = 1000; p[2][2] = 0; p[2][3] = 1000; p[2][4] = 1000; p[2][5] = 1;
p[3][0] = 1; p[3][1] = 1000; p[3][2] = 1000; p[3][3] = 0; p[3][4] = 4; p[3][5] = 3;
p[4][0] = 1000; p[4][1] = 5; p[4][2] = 1000; p[4][3] = 4; p[4][4] = 0; p[4][5] = 2;
p[5][0] = 1000; p[5][1] = 1000; p[5][2] = 1; p[5][3] = 3; p[5][4] = 2; p[5][5] = 0;
int smallest;
if (rank == 0)
{
//transpose(&p , row , col);
smallest = 0;
vt[smallest] = smallest;
//MPI_Bcast();
}
int vt1, d1;
vt1 = d1 = 0;
int roww[col];
MPI_Scatter(vt, 1, MPI_INT, &vt1, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(d, 1, MPI_INT, &d1, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(&p[0][0], col, MPI_INT,roww, col, MPI_INT, 0, MPI_COMM_WORLD);
i = 0;
while (i < (row*row)/size)
{
MPI_Bcast(&smallest, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (vt1 != rank)
{
if (roww[smallest] != 1000)
{
if (d1 > roww[smallest])
d1 = roww[smallest];
}
}
MPI_Gather(&d1, 1, MPI_INT, d, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
{
smallest = d[0];
int k = 1;
int index = 0;
while (k < 6)
{
if (d[k] < smallest)
{
smallest = d[k];
index = k;
}
k++;
}
vt[k] = index;
}
MPI_Scatter(vt, 1, MPI_INT, &vt1, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(d, 1, MPI_INT, &d1, 1, MPI_INT, 0, MPI_COMM_WORLD);
i++;
}
free(p[0]);
free(p);
MPI_Finalize();
return 0;
}
- 在 C++ 中传递字符串时指针无效
- free():仅在一种情况下指针无效
- free():实现矢量擦除()时的指针无效
- free():添加字符串时指针无效
- C++ ecliipse free():函数末尾的指针无效
- C++ 指针无效函数问题
- 将 boost::object_pool 与矢量一起使用时指针无效
- free():矢量 C++ 的指针无效<vec4i>
- omnet++free():指针无效,错误134/139
- 在OpenCV中调用stereoRectify会导致异常:帧指针无效
- 销毁和重新创建一个对象会使指向该对象的所有指针无效吗
- 用户定义类中的Null指针无效
- 删除指向类的指针无效
- 运行GTest时指针无效
- C++错误消息:指针无效
- 可以std::string reconfiguration使指向堆的指针无效
- 为什么删除指向指针向量的指针会导致指针无效
- MPI_scatter:缓冲区指针无效
- mmap 错误:分段错误/指针无效错误
- 返回 std::string 时指针无效(libc 如此说)