提升反序列化期间出错

Error during Boost Deserialization

本文关键字:出错 反序列化      更新时间:2023-10-16

我正在使用 Boost 序列化来序列化 Eigen MatrixXd,并类似地尝试使用下面提供的方法从存储的文件中反序列化load_data。我看到虽然文件退出,但 c++ 编译器总是抛出错误"分段错误(核心转储)"。请推荐。

#include "Serialize_data.h"
#include "CommonUtils.h"
struct RandomNode1 {
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version) {
        ar & random_feature_indices_;
    }
    MatrixXd random_feature_indices_;
};
namespace boost {
template<class Archive, typename _Scalar, int _Rows, int _Cols, int _Options,
        int _MaxRows, int _MaxCols>
inline void serialize(Archive & ar,
        Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> & t,
        const unsigned int file_version = 4209360273818925922L) {
    int rows = t.rows(), cols = t.cols();
    ar & rows;
    ar & cols;
    ar & boost::serialization::make_array(t.data(), rows * cols);
}
}
void save_data(MatrixXd vals) {
    // create and open a character archive for output
    ofstream ofs("filename.data");
    RandomNode1 r;
    r.random_feature_indices_ = vals;
    // save data to archive
    {
        boost::archive::text_oarchive oa(ofs);
        oa << r;
    }
    ofs.close();
}
void load_data(string path) {
    ifstream ifs(path);
    RandomNode1 r1;
    if (ifs.good()) {
        boost::archive::text_iarchive ia(ifs);
        ia >> r1;
    } else {
        cerr << "Error loading file";
        assert(false);
    }
}

您选择了具有动态维度的矩阵类型

  • MatrixXd 的文档

    typedef Matrix< double , Dynamic , Dynamic > MatrixXd
    

这意味着,如果从存档还原,则必须主动确保也还原维度。这不会在这里发生:

int rows = t.rows(), cols = t.cols();
ar & rows;
ar & cols;

实际上,它在加载之前使用矩阵的完全不相关的默认维度初始化rowscols。并且它无法在从存档中读取rowscols后设置尺寸。

不出所料,下一步

ar & boost::serialization::make_array(t.data(), rows * cols);

不会成功,除非实际矩阵类型恰好具有足以容纳rows * cols元素的默认维度。

展示如何做至少MatrixXd的事情:

namespace boost { namespace serialization {
    template<class Archive>
        inline void save(Archive & ar, MatrixXd const& t, unsigned int /*file_version*/) 
        {
            int rows = t.rows(), cols = t.cols();
            ar & rows;
            ar & cols;
            ar & boost::serialization::make_array(t.data(), rows * cols);
        }
    template<class Archive>
        inline void load(Archive & ar, MatrixXd & t, unsigned int /*file_version*/) 
        {
            int rows, cols;
            ar & rows;
            ar & cols;
            t = MatrixXd(rows, cols);
            ar & boost::serialization::make_array(t.data(), rows * cols);
        }
} }
BOOST_SERIALIZATION_SPLIT_FREE(MatrixXd)

这在瓦尔格林德下干净利落地运行。