我的mpi程序是这样的:
........
MPI_Status status1;
.......
MPI_Recv(rb,buf_size,MPI_INT,prcid,1,MPI_COMM_WORLD,&status1);
.....
这个程序运行良好。 但是当我改变它时:
........
MPI_Status* status2;
.......
MPI_Recv(rb,buf_size,MPI_INT,prcid,1,MPI_COMM_WORLD,status2);
.....
它无法正常运行并出现错误:
erro: Segmentation fault (signal 11)
没有&status1
等于status2
?
他们之间有什么区别? 谢谢 !
答案 0 :(得分:5)
不,它们不是等价的,虽然你每次都传递相同的类型参数,这就是编译器不抱怨的原因。
在一种情况下,您传递已在堆栈上分配的结构的地址。
在另一种情况下,您传递的指针指向内存中的某个任意(可能是不可写)位置,因为它未初始化。
您可以使用malloc
修复第二个调用以分配内存并将指针指向它。
MPI_Status* status2 = malloc(sizeof(MPI_Status));
当然,在你完成它之后,你应该负责并且free()
那个记忆:
free(status2);
答案 1 :(得分:5)
在第一种情况下,status1
是一个对象,因此&status1
是指向MPI_Recv
可以写入的有效对象的指针。
在第二种情况下,status2
是未初始化的指针。它的值可能是一些随机堆栈垃圾,所以当MPI_Recv
尝试写入它时,它会写入一些随机内存位置。很多内存都不喜欢被写入,所以你得到一个段错误。你也可能会得到一些微妙的内存损坏,以后会引起奇怪的问题。
如果您尝试这样做,它应该有效:
MPI_Status status1;
MPI_Status* status2 = &status1;
.......
MPI_Recv(rb,buf_size,MPI_INT,prcid,1,MPI_COMM_WORLD,status2);