0

我是 MPI 的初学者,我正在使用 C 语言和处理器模拟器 (MPICH2),我编写了以下代码来发送一个 2D 数组以使 2 个处理器从中取一条线,但在运行 MPICH2 时会产生错误,代码是:

#include <stdio.h>  
#include <stdlib.h>  
#include "mpi.h"

int main(int argc, char *argv[]) {
    int rank;
    int commsize;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD,&commsize);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    char** name=malloc(2*sizeof(char*));
    int i;

    for(i=0;i<2;i++){
        name[i]=malloc(15*sizeof(char));
    }
    name[0]="name";
    name[1]="age";
    /////////////////////
    if(rank==0) {
        char** mArray=malloc(2*sizeof(char*));
        MPI_Scatter(&name,1,MPI_CHAR,&mArray,1,MPI_CHAR,0,MPI_COMM_WORLD);//send
    }
    else {
        char** mArray=malloc(2*sizeof(char*));
        int k;

        for(k=0;k<2;k++){
            mArray[k]=malloc(15*sizeof(char));
        }
        MPI_Scatter(&mArray,1,MPI_CHAR,&mArray,1,MPI_CHAR,0,MPI_COMM_WORLD);//receive       
        printf("line is %s \n",mArray[rank-1]);
    }
    MPI_Finalize();
}
4

2 回答 2

3
  name[0]="name";

  name[1]="age";

这不是字符串副本。嗯,不像你可能认为的那样。您分配了空间并将其分配给 name[0] 和 name[1],然后用指向文字字符串“name”和“age”的指针覆盖这些指针。您分配的 char[15] 数组丢失(内存泄漏)。

然后,当您尝试使用 MPI_Scatter 发送它时,您实际上是在发送name指向的内容,这是一个指针,而不是字符串。(以下-->表示指向)

name --> [0x4321, 0x2348]
0x4321 --> "name"
0x2348 --> "age"

但是你分散(至少部分)[0x4321, 0x2348]甚至更多。

我以前没有使用过 MPI 库(我记得),但我怀疑你对 MPI_Scatter 的其他参数也不正确,因为误解了字符串(字符数组)和指针。

我认为如果你这样做:

char name[2][15] = {"name", "age"};

并在代码的分散部分忘记了你的 malloc,你会更轻松,尽管很多很多次尝试使用 2d C 数组也会让你搞砸。这里的很多问题是由于人们误解了指向数组的指针数组和二维数组之间的区别。

于 2010-05-19T22:21:14.863 回答
0

正如 nategoose 指出的那样,您的字符串定义都是错误的。先解决这些问题,在你能解决之前不要打扰 MPI 调用printf()。此外,Scatter 仅当age字符串直接跟随name内存中的字符串时才起作用:否则,它将用垃圾填充消息的第二部分(或直接出现段错误)。我不确定是否

char name[2][15] = {"name", "age"};

会将两个字符串彼此相邻放置,或者它只是将两个指针彼此相邻放置,指向内存中的任何位置。如果是前者,那么就使用它。否则,我建议您根本不要使用二维数组,而是像这样声明您的字符串:

char[2*15] name = "name";
sprintf(name+15, "age");

您的 Scatter 参数也是错误的。第一个参数应该是name,而不是&name:Scatter 需要一个指针,传递&name将导致它尝试发送name的内存地址而不是其内容。

第二个和第五个参数也不对:你想发送 30 个字符(因为它是一个 2*15 数组),而不仅仅是 1。

于 2010-05-20T18:51:01.273 回答