其他分享
首页 > 其他分享> > c-Boost序列化段错误

c-Boost序列化段错误

作者:互联网

我正在尝试序列化类成员.以下代码片段将显示相关的类定义以及我所包含的非侵入式序列化代码.我在saveHashTable()方法期间遇到段错误,该方法试图序列化类成员shash_table_.这是代码的完整修剪版本:

#include <map>
#include <string>
#include <vector>
#include <set>
#include <fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/set.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/list.hpp>

using namespace std;

struct ORROctree
    {
      public:
        struct Node
        {
          public:
            struct Data
            {               
              public:
                float n_[3], p_[3];
                int id_x_, id_y_, id_z_, lin_id_, num_points_;
                std::set<Node*> neighbors_;
                void *user_data_;
            };

          public: 
            Node::Data *data_;
            float center_[3], bounds_[6], radius_;
            Node *parent_, *children_;
        };        
      protected:
        float voxel_size_, bounds_[6];
        int tree_levels_;
        Node* root_;
        std::vector<Node*> full_leaves_;                  
    };

struct ModelLibrary
{  

    template <typename T, typename REAL = float>    
    struct NDIMVoxelStructure 
    {
        T *voxels_;        
        std::vector<int> total_num_of_voxels_i_;
        std::vector<int> num_of_voxels_;
        long total_num_of_voxels_;
        std::vector<REAL> bounds_;
        std::vector<REAL> spacing_; 
        std::vector<REAL> min_center_;
};


    typedef std::pair<const ORROctree::Node::Data*, const ORROctree::Node::Data*>  Dipole;
    struct Base {
         Dipole seg1;
         Dipole seg2;
    };
    typedef std::list<Base> bases_list;
    typedef std::map <string, bases_list> SerializeHashTableCell;
    // MEMBER TO BE SERIALIZED
    typedef NDIMVoxelStructure<SerializeHashTableCell> SerializeHashTable;

  public:
    SerializeHashTable shash_table_;

  public:
    bool saveHashTable();

    bool loadHashTable();
};



// SERIALIZATION METHODS FOR THE TYPES USED TO FORM THE SERIALIZEHASHTABLE


namespace boost {
namespace serialization {

template<class Archive>
inline void serialize(Archive & ar, ModelLibrary::SerializeHashTable & h, const unsigned int version)
{
  ar & h.total_num_of_voxels_;
  ar & boost::serialization::make_array(h.voxels_, h.total_num_of_voxels_);
  ar & h.num_of_voxels_;
  ar & h.total_num_of_voxels_i_;
  ar & h.bounds_;
  ar & h.spacing_;
  ar & h.min_center_;
}


template<class Archive>
inline void serialize(Archive & ar, ModelLibrary::Base & b, const unsigned int version)
{
  ar & b.seg1;
  ar & b.seg2;
}


template<class Archive>
inline void serialize(Archive & ar, ORROctree::Node n, const unsigned int version)
{
  ar & n.data_;
  ar & n.center_;
  ar & n.bounds_;
  ar & n.radius_;
  ar & n.parent_;
  ar & n.children_;
}

template<class Archive>
inline void serialize(Archive & ar, ORROctree::Node::Data d, const unsigned int version)
{
  ar & d.id_x_;
  ar & d.id_y_;
  ar & d.id_z_;
  ar & d.neighbors_;
  ar & d.lin_id_;
  ar & d.num_points_;
  ar & d.p_;
}
}
}

bool ModelLibrary::saveHashTable ()
{
    std::ofstream ofs("test.txt");
    boost::archive::text_oarchive oa(ofs);
    oa << shash_table_;
    return true;
}


bool
ModelLibrary::loadHashTable ()
{
    std::ifstream ifs("test.txt");
    boost::archive::text_iarchive ia(ifs);
    ia >> shash_table_;
    return true;
}


int main() 
{
    ModelLibrary m;
    m.saveHashTable();
}

解决方法:

您只需要初始化数据结构中的数据即可.所有未明确初始化的原始类型都将具有不确定的(“随机”)值.这包括指针,这意味着您通过将指针解引用到随机内存位置来调用Undefined Behaviour.

这是一个可能进行的最简单初始化的更新,它可以在Valgrind下正常运行.那是个好工具.用它!

另外,启动编译器消息(对于gcc / clang,至少-Wall -Wextra -pedantic).

在各个地方添加:

Data() : id_x_(0), id_y_(0), id_z_(0), lin_id_(0), num_points_(0), user_data_(0)
{
    std::fill(n_, n_+3, 0);
    std::fill(p_, p_+3, 0);
}
Node() : data_(0), radius_(0), parent_(0), children_(0) 
{
    std::fill(center_, center_+3, 0);
    std::fill(bounds_, bounds_+6, 0);
}
ORROctree() : voxel_size_(0), tree_levels_(0), root_(0)
{
    std::fill(bounds_, bounds_+6, 0);
}
NDIMVoxelStructure() : voxels_(0), total_num_of_voxels_(0) 
{ }
Base() : seg1(0, 0), seg2(0, 0) 
{ }

看到它Live On Coliru

更新来自评论:以下几行显然是错误的:

inline void serialize(Archive & ar, ORROctree::Node n, const unsigned int version)
inline void serialize(Archive & ar, ORROctree::Node::Data d, const unsigned int version)

而且应该读

inline void serialize(Archive & ar, ORROctree::Node& n, const unsigned int version)
inline void serialize(Archive & ar, ORROctree::Node::Data& d, const unsigned int version)

标签:c,boost,boost-serialization
来源: https://codeday.me/bug/20191013/1907045.html