Boost反序列化期间出错

时间:2014-02-27 20:14:09

标签: c++ serialization boost segmentation-fault deserialization

我使用Boost序列化来序列化Eigen MatrixXd,同样尝试使用load_data方法从存储的文件中反序列化,如下所示。我看到虽然文件退出,但c ++编译器总是抛出错误“Segmentation fault(core dumped)”。请推荐。

#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);
    }
}

1 个答案:

答案 0 :(得分:2)

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

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

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)

这在valgrind下运行得很干净。