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

使用Boost.MPI序列化类中二维数组指针时遇序列化错误求助

问题分析与解决

错误原因

你遇到的error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘int’错误,根源在于:

  • register_type仅用于多态类类型的序列化,用来识别派生类,对int**这种基本类型指针完全无效,你误用了这个方法。
  • Boost序列化无法自动处理int**这种动态分配的二维裸指针——它不知道数组的维度信息,直接序列化指针会导致库尝试将其当作普通对象处理,触发错误。
  • 错误地将Dummy特化为is_mpi_datatype,这个特性只适用于MPI原生支持的数据类型,自定义序列化类型不需要该特化,反而会干扰Boost MPI的序列化流程。

解决方案

要正确序列化动态二维数组,需要手动控制序列化流程:先序列化数组尺寸m_N,再逐行序列化每一个一维数组的元素。同时修复MPI类型特化问题,并补充拷贝构造逻辑避免浅拷贝导致的内存错误。

修改后的完整代码

#include <iostream>
#include <set>
#include <map>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/mpi.hpp> 
#include <boost/serialization/array.hpp>
#include <algorithm>

class Dummy 
{
private: 
    int m_N;
    int** array; 
    friend class boost::serialization::access;
    template <class Archive>
    void serialize(Archive &ar, const unsigned int /*version*/)
    {
        ar & m_N; 
        // 逐行序列化一维数组,明确告知数组长度
        for (int i = 0; i < m_N + 1; ++i) {
            ar & boost::serialization::make_array(array[i], m_N + 1);
        }
    }

    // 封装内存分配逻辑
    void allocate_memory(int N) {
        m_N = N;
        array = new int*[N+1];
        for(auto i=0; i < N+1; ++i) {
            array[i] = new int[N+1];
        }
    }

public:
    Dummy() : m_N(0), array(nullptr) {}; 
    Dummy(const int N) {
        allocate_memory(N);
    };

    // 拷贝构造函数:避免浅拷贝导致的内存重复释放
    Dummy(const Dummy& other) {
        allocate_memory(other.m_N);
        for (int i = 0; i < m_N + 1; ++i) {
            std::copy(other.array[i], other.array[i] + m_N + 1, array[i]);
        }
    }

    // 赋值运算符重载
    Dummy& operator=(const Dummy& other) {
        if (this != &other) {
            // 释放当前内存
            for(auto i=0; i < m_N + 1; ++i) {
                delete[] array[i];
            }
            delete[] array;
            // 重新分配内存并拷贝数据
            allocate_memory(other.m_N);
            for (int i = 0; i < m_N + 1; ++i) {
                std::copy(other.array[i], other.array[i] + m_N + 1, array[i]);
            }
        }
        return *this;
    }

    ~Dummy() {
        if (array != nullptr) {
            for(auto i=0; i < m_N + 1; ++i) {
                delete[] array[i];
            }
            delete[] array;
        }
    }; 
};

// 移除错误的is_mpi_datatype特化

int main(int argc, char* const argv[]) 
{
    boost::mpi::environment   env; 
    boost::mpi::communicator  world; 
    std::map<int,std::vector<Dummy>> IdToVecObject;
    std::vector<Dummy> vec; 
    std::set<int> neigbours; 

    if(world.rank() == 0) {   
        Dummy obj(1); 
        vec.push_back(obj); 
        neigbours.insert(1); 
        IdToVecObject.emplace(1, vec); 
    }
    if(world.rank() == 1) {
        Dummy obj(1); 
        vec.push_back(obj); 
        neigbours.insert(0); 
        IdToVecObject.emplace(0, vec); 
    }

    for(auto& it : IdToVecObject) {
        int target = it.first;
        Dummy obj(1); 
        world.send(target, 0, obj); 
    }

    for(auto i : neigbours) {
        int source = i ;  
        Dummy obj(1); 
        world.recv(source, 0, obj); 
    }

    return 0; 
}

关键修改说明

  • 序列化逻辑调整:使用boost::serialization::make_array明确指定每一行数组的长度,让序列化库正确处理数组内容,而非直接序列化裸指针。
  • 移除MPI类型特化:删除is_mpi_datatype<Dummy>的特化,Boost MPI会自动借助Boost Serialization处理自定义类型。
  • 补充拷贝构造与赋值逻辑:避免默认浅拷贝导致的内存重复释放问题,确保对象拷贝时完整复制数组数据。
  • 空指针安全处理:析构函数中增加空指针判断,避免非法内存释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:24:54