C++ MPI#u发送MPI#u Recv segfault在C+中+;

C++ MPI#u发送MPI#u Recv segfault在C+中+;,c++,mpi,C++,Mpi,我已经用MPI编写了一个简单的程序,它在处理器之间发送和接收消息,但运行时存在分段错误 这是我的全部代码 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string> #include <string.h> #include <strings.h> #include <sstream> #include<mpi.h&

我已经用MPI编写了一个简单的程序,它在处理器之间发送和接收消息,但运行时存在分段错误

这是我的全部代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <strings.h>
#include <sstream>
#include<mpi.h>
using namespace std;
class Case {
public:
    int value;
    std::stringstream sta;
};
int main(int argc, char **argv) {
     int rank,size;
     MPI::Init(argc,argv);
     rank=MPI::COMM_WORLD.Get_rank();
     size=MPI::COMM_WORLD.Get_size();
     if(rank==0){
        Case *s=new Case();
        s->value=1;
        s->sta<<"test";
        cout<<"\nInside send before copy value  :"<<s->value;
        fflush(stdout);
        cout<<"\nInside send before copy data  :"<<s->sta.str();
        fflush(stdout);
        Case scpy;
        scpy.value=s->value;
        scpy.sta<<(s->sta).rdbuf();
        cout<<"\nInside send after copy value  :"<<scpy.value;
        cout<<"\nInside send after copy value  :"<<scpy.sta.str();
        MPI::COMM_WORLD.Send(&scpy,sizeof(Case),MPI::BYTE,1,23);
     }
     MPI::COMM_WORLD.Barrier();
     if(rank==1){
        Case r;
        MPI::COMM_WORLD.Recv(&r,sizeof(Case),MPI::BYTE,0,23);
        cout<<"\nRecieve value"<<r.value;
        fflush(stdout);
        cout<<"\nRecieve data"<<r.sta;
        fflush(stdout);
     }
     MPI::Finalize();
     return 0;
}
问题 我认为问题在于线路:

MPI::COMM_WORLD.Send(&scpy,sizeof(Case),MPI::BYTE,1,23);
向接收方发送Case结构的副本,但它发送的是字节的原始副本,这不是很有用。stringstream类将包含指向用于存储字符串的实际内存的指针,因此此代码将:

  • 向接收方发送指针(包含对接收方毫无意义的地址)
  • 不发送字符串的实际内容
  • 当接收器尝试取消引用无效指针时,将出现seg故障

    修正1 解决这个问题的一种方法是自己发送字符数据

    在这种方法中,您将发送一条指向std::stringstream::str()::c_str()的消息,其长度为std::stringstream::str()::size()*sizeof(char)

    修正2 另一种似乎更适合尝试使用MPI和字符串的方法是使用Boost库。Boost包含自动为您序列化数据的MPI函数

    关于Boost和MPI的有用教程可用。 下面是该教程中执行类似任务的示例代码:

    #include <boost/mpi.hpp>
    #include <iostream>
    #include <string>
    #include <boost/serialization/string.hpp>
    namespace mpi = boost::mpi;
    
    int main(int argc, char* argv[]) 
    {
      mpi::environment env(argc, argv);
      mpi::communicator world;
    
      if (world.rank() == 0) {
        world.send(1, 0, std::string("Hello"));
        std::string msg;
        world.recv(1, 1, msg);
        std::cout << msg << "!" << std::endl;
      } else {
        std::string msg;
        world.recv(0, 0, msg);
        std::cout << msg << ", ";
        std::cout.flush();
        world.send(0, 1, std::string("world"));
      }
    
      return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    名称空间mpi=boost::mpi;
    int main(int argc,char*argv[])
    {
    环境环境(argc,argv);
    mpi::通信器世界;
    if(world.rank()==0){
    send(1,0,std::string(“Hello”);
    std::字符串msg;
    recv(1,1,msg);
    标准::cout
    
    #include <boost/mpi.hpp>
    #include <iostream>
    #include <string>
    #include <boost/serialization/string.hpp>
    namespace mpi = boost::mpi;
    
    int main(int argc, char* argv[]) 
    {
      mpi::environment env(argc, argv);
      mpi::communicator world;
    
      if (world.rank() == 0) {
        world.send(1, 0, std::string("Hello"));
        std::string msg;
        world.recv(1, 1, msg);
        std::cout << msg << "!" << std::endl;
      } else {
        std::string msg;
        world.recv(0, 0, msg);
        std::cout << msg << ", ";
        std::cout.flush();
        world.send(0, 1, std::string("world"));
      }
    
      return 0;
    }