0

私は MPI の初心者で、C 言語と Simulator for Processors (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";

これは文字列のコピーではありません。まあ、おそらくそうであるとは思わないでしょう。スペースを malloc して name[0] と name[1] に割り当ててから、これらのポインターをリテラル文字列 "name" と "age" へのポインターで上書きします。malloc した char[15] 配列が失われます (メモリ リーク)。

次に、MPI_Scatter を使用して送信しようとすると、実際にnameは文字列ではなくポインターであるポイントを送信しています。(以下-->は指すことを意味します)

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

しかし、あなたは散らばっています(少なくとも一部)[0x4321, 0x2348]、そしておそらくそれ以上です。

以前に MPI ライブラリを使用したことはありませんが (覚えています)、文字列 (文字配列) とポインターの誤解のために、MPI_Scatter への他の引数も正しくないと思われます。

あなたがしたと思います:

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

コードのスキャッター部分で malloc を忘れた方が簡単ですが、2 次元 C 配列を何度も使用しようとすると、同様に混乱してしまいます。ここでの多くの質問は、配列へのポインターの配列と 2 次元配列の違いを人々が誤解しているためです。

于 2010-05-19T22:21:14.863 に答える
0

nategooseが指摘しているように、文字列の定義はすべて間違っています。それらを最初に修正し、できるまでMPI呼び出しを気にしないでprintf()ください。さらに、Scatterは、文字列がメモリ内の文字列に直接age続く場合にのみ機能します。それ以外の場合は、メッセージの2番目の部分がジャンク(またはセグメンテーション違反)で埋められます。nameわからない

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

2つの文字列を隣り合わせに配置するか、メモリ内の任意の場所を指す2つのポインタを並べて配置します。前者の場合は、これを使用してください。それ以外の場合は、2D配列をまったく使用せず、次のように文字列を宣言することをお勧めします。

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

Scatterのパラメータも間違っています。最初のパラメータはname、ではなく、である必要があり&nameます。Scatterはポインタを予期します。渡すと、その内容ではなく、のメモリアドレスの&name送信が試行されます。name

2番目と5番目のパラメーターも正しくありません。1文字だけでなく30文字を送信する必要があります(2 * 15配列であるため)。

于 2010-05-20T18:51:01.273 に答える