You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ MPI项目中MPI_Send发送char数组向量接收错误如何解决

MPI发送char数组向量异常的原因与修复方案

问题根因

  • 核心逻辑错误:vector<char*>存储的是内存指针,指针仅在当前进程的地址空间有效,跨进程发送指针本身毫无意义,接收进程拿到的是野指针,无法访问到对应字符串内容。
  • MPI调用参数错误:MPI_Send(&cstrings[0], cstrings.size(), MPI_CHAR,...)仅发送了2个字节的内容(对应两个char指针的前2个字节),完全没有发送字符串的实际存储内容。
  • 临时对象悬空引用:构造cstrings时,循环内的string st是局部临时变量,循环结束后立即销毁,存储的&st[0]属于悬空指针,即使在进程0本地后续访问也属于未定义行为,打印正常只是内存未被覆盖的巧合。

修复方案

这里采用序列化所有字符串到连续缓冲区的方案,实现简单且通信次数少,步骤如下:

  1. 进程0先统计所有字符串的总长度(包含每个字符串的\0结束符),构造连续的char缓冲区,把所有字符串依次拷贝到缓冲区中
  2. 先发送总长度给接收进程,接收进程申请对应大小的缓冲区后接收完整的字符内容
  3. 接收进程再从缓冲区中拆分出各个字符串

修正后可运行代码

#include "mpi.h"
#include <iostream>
#include <string>
#include <vector>
#include <cstring>

using namespace std;

int main(int argc, char **argv) {
  int rank, numprocs;

  MPI_Init(NULL, NULL);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

  if (rank==0) {
    std::vector<std::string> strings = {"fe", "fo"};
    // 计算总长度,每个字符串加1存'\0'
    int total_len = 0;
    for (auto& s : strings) {
      total_len += s.size() + 1;
    }
    // 构造连续缓冲区
    std::vector<char> send_buf(total_len);
    int offset = 0;
    for (auto& s : strings) {
      strcpy(send_buf.data() + offset, s.c_str());
      offset += s.size() + 1;
    }
    // 先发总长度,再发内容
    MPI_Send(&total_len, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
    MPI_Send(send_buf.data(), total_len, MPI_CHAR, 1, 1, MPI_COMM_WORLD);
  }
  if (rank==1) {
    int total_len = 0;
    // 先收总长度,申请缓冲区
    MPI_Recv(&total_len, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    std::vector<char> recv_buf(total_len);
    MPI_Recv(recv_buf.data(), total_len, MPI_CHAR, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    // 拆分字符串
    std::vector<std::string> recv_strings;
    int offset = 0;
    while (offset < total_len) {
      std::string s(recv_buf.data() + offset);
      recv_strings.push_back(s);
      offset += s.size() + 1;
    }
    // 打印验证
    for (auto& s : recv_strings) {
      cout << s << endl;
    }
  }

  MPI_Finalize();
  return 0;
}

内容的提问来源于stack exchange,提问作者Giulio Mattolin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:15:03