使用 boost::serialization 保存数据时出现 Seg 错误

Posted

技术标签:

【中文标题】使用 boost::serialization 保存数据时出现 Seg 错误【英文标题】:Seg fault when saving data using boost::serialization 【发布时间】:2012-04-06 01:17:37 【问题描述】:

在尝试使用 boost 序列化保存数据库时,我遇到了无法解决的段错误。你能帮忙吗?任何建议都将不胜感激。 我已将下面的声明确定为罪魁祸首,但不知道如何解决它

oa << *this;

我的代码部分如下:

template<class Archive>
void nDB::serialize(Archive &ar, const unsigned int version) 
    ar & _LAYERS;
    ar & _MACROS;
    ar & _MODULES;
    ar & _INSTS;


void nDB::save_db(string filename) 
    std::ofstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
    //assert(ofs.good());
    boost::archive::binary_oarchive oa(ofs);
    oa << *this;
    ofs.close();

嗨, 我能够将问题指向我数据库中的循环引用。代码如下:

    template<class Archive>
    void pin::serialize(Archive &ar, const unsigned int version) 
    ar & pin_Port;
    ar & pin_Layer;
    

    template<class Archive>
    void port::serialize(Archive & ar, const unsigned int version)
    ar & port_Name;
    ar & port_Use;
    ar & port_Dir;
    ar & port_PINS;
    

你好,下面是我的类定义

    class pin 
    public:
    port*       pin_Port;
    layer*      pin_Layer;
    // rect*       pin_shape;

    pin();
    ~pin();

    void         set_port(port*);
    void         set_layer(layer*);
    string       get_name();
    port*        get_port();
    layer*       get_layer();
    string       get_layer_name();
    double       get_layer_width();
    private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version);
    ;
    class port 
    public:
    string     port_Name;
    char       port_Use;
    char       port_Dir;
    pin_vector port_PINS;
    port();
    ~port();

    void         set_name(string);
    void         set_use(int);
    void         set_dir(int);
    string       get_name(void);
    string       get_use(void);
    string       get_dir(void);
    void         add_pin(pin*);
    pin_vector   get_all_pins(void);

    private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version);
    ;

【问题讨论】:

【参考方案1】:

我怀疑罪魁祸首是ofs.close();binary_oarchive 对象需要在基础流关闭之前超出范围,因为binary_oarchive 对象会尝试写入剩余数据并在其析构函数中刷新流。

标准流在超出范围时会自动刷新和关闭,因此该行完全没有必要(在这种情况下是有害的)。删除它,你应该很高兴。

(不相关,但_LAYERS_MACROS等是可怕的名称,实际上在用户代码中是非法的。最好去掉前导下划线或大写字母两者。)

【讨论】:

嗨,ildjarn,我已经按照你的建议做了,但没有解决。您还看到代码有什么其他问题吗?谢谢 ildjarn @Binh :不,您没有显示足够的代码来判断。 ;-] 对于目前显示的代码,只需删除ofs.close(); 即可使其处于良好状态,因此您的问题一定出在未显示的代码中。 感谢 ildjarn,您说的完全正确。我能够将问题归结为我数据库中的循环引用。我为调试所做的是依次关闭每个类的序列化函数中的每个组件。最后,我能够确定它来自循环引用。现在我想我的问题将集中在如何让 boost 序列化处理循环引用,否则根本不可能。我的循环引用代码如下: 哎呀,你知道如何在评论部分添加代码吗?谢谢 ildjarn, @Binh :最好将其编辑到您的问题中,以便正确格式化。

以上是关于使用 boost::serialization 保存数据时出现 Seg 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 boost::serialization 序列化 std::vector?

如何为 boost::serialization 指定一个 nvp 包装器?

对 boost::serialization 的未定义引用

如何让 boost::serialization 工作?

使用 boost::serialization 时如何刷新文件缓冲区?

使用 boost::serialization 序列化一个包含 boost adjacency_list 作为成员的类