升压序列化段错误 [英] Boost Serialization Segfault

查看:159
本文介绍了升压序列化段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图序列化类成员。 code的下面的片段将展示相关类的定义和非介入式序列code我已经包括在内。我该尝试序列化类成员shash_table_我saveHashTable()方法的过程中获得一个段错误。这里是code的自包含修剪版本

 的#include<地图和GT;
#包括LT&;串GT;
#包括LT&;矢量>
#包括LT&;集>
#包括LT&;&的fstream GT;
#包括LT&;升压/存档/ text_iarchive.hpp>
#包括LT&;升压/存档/ text_oarchive.hpp>
#包括LT&;升压/系列化/ vector.hpp>
#包括LT&;升压/系列化/ set.hpp>
#包括LT&;升压/系列化/ utility.hpp>
#包括LT&;升压/系列化/ map.hpp>
#包括LT&;升压/系列化/ list.hpp>使用命名空间std;结构ORROctree
    {
      上市:
        结构节点
        {
          上市:
            数据结构
            {
              上市:
                浮N_ [3],P_ [3];
                INT id_x_,id_y_,id_z_,lin_id_,num_points_;
                的std ::集<节点* GT; neighbors_;
                无效* user_data_;
            };          上市:
            节点::数据* data_中的数据;
            浮动中心_ [3],bounds_ [6],radius_;
            节点* PARENT_,* children_;
        };
      保护:
        浮voxel_size_,bounds_ [6];
        INT tree_levels_;
        节点* root_;
        的std ::矢量<节点* GT; full_leaves_;
    };结构ModelLibrary
{    模板< typename的T,typename的REAL =浮动>
    结构NDIMVoxelStructure
    {
        T * voxels_;
        的std ::矢量<&INT GT; total_num_of_voxels_i_;
        的std ::矢量<&INT GT; num_of_voxels_;
        长total_num_of_voxels_;
        的std ::矢量<&REAL GT; bounds_;
        的std ::矢量<&REAL GT;间距_;
        的std ::矢量<&REAL GT; min_center_;
};
    的typedef的std ::对<常量ORROctree ::节点::数据*,常量ORROctree ::节点::数据*>偶极子;
    结构基地{
         偶极SEG1;
         偶极SEG2;
    };
    的typedef的std ::名单<基地以及GT; bases_list;
    的typedef的std ::地图<字符串,bases_list> SerializeHashTableCell;
    //成员被序列化
    typedef的NDIMVoxelStructure< SerializeHashTableCell> SerializeHashTable;  上市:
    SerializeHashTable shash_table_;  上市:
    布尔saveHashTable();    布尔loadHashTable();
};//序列化方法用于形成的SERIALIZEHASHTABLE类型
名字空间boost {
命名空间序列{模板<类归档和GT;
内嵌无效连载(归档和放大器; AR,ModelLibrary :: SerializeHashTable&放大器; H,const的无符号整型版)
{
  AR&安培; h.total_num_of_voxels_;
  AR&安培;提高::系列化:: 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_;
}
模板<类归档和GT;
内嵌无效连载(归档和放大器; AR,ModelLibrary ::基地和b,const的无符号整型版)
{
  AR&安培; b.seg1;
  AR&安培; b.seg2;
}
模板<类归档和GT;
内嵌无效连载(归档和放大器; AR,ORROctree ::节点n,const的无符号整型版)
{
  AR&安培; n.data_;
  AR&安培; n.center_;
  AR&安培; n.bounds_;
  AR&安培; n.radius_;
  AR&安培; n.parent_;
  AR&安培; n.children_;
}模板<类归档和GT;
内嵌无效连载(归档和放大器; AR,ORROctree ::节点::数据D,const的无符号整型版)
{
  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_;
}
}
}布尔ModelLibrary :: saveHashTable()
{
    的std :: OFS的ofstream(的test.txt);
    提高::档案:: text_oarchive的OA(OFS);
    OA<< shash_table_;
    返回true;
}
布尔
ModelLibrary :: loadHashTable()
{
    性病:: ifstream的IFS(的test.txt);
    提高::档案:: text_iarchive IA(IFS);
    IA>> shash_table_;
    返回true;
}
诠释的main()
{
    ModelLibrary米;
    m.saveHashTable();
}


解决方案

您只需要在你的数据结构来初始化数据。尚未明确地初始化所有基本类型将具有的不确定的(随机)的值。这包括三分球,这意味着你通过调用 未定义行为 取消引用指针随机内存位置。

下面是与那些可能工作的最简单的初始化一个更新,它Valgrind的下运行干净。这是一个很好的工具。使用它!

此外,曲柄了编译器消息( -Wall -pedantic -Wextra 至少为GCC /铛)。

添加在不同的地方:

 数据():id_x_(0),id_y_(0),id_z_(0),lin_id_(0),num_points_(0),user_data_(0)
{
    的std ::填充(N_,N_ + 3,0);
    的std ::填充(P_,P_ + 3,0);
}
节点():data_中的数据(0),radius_(0),PARENT_(0),children_(0)
{
    的std ::填充(中心_,中心_ + 3,0);
    的std ::填充(bounds_,bounds_ + 6,0);
}
ORROctree():voxel_size_(0),tree_levels_(0),root_(0)
{
    的std ::填充(bounds_,bounds_ + 6,0);
}
NDIMVoxelStructure():voxels_(0),total_num_of_voxels_(0)
{}
基():SEG1(0,0),SEG2(0,0)
{}

看它的 住在Coliru

更新从注释:以下行的错误显然是:

 内嵌无效连载(归档和放大器; AR,ORROctree ::节点n,const的无符号整型版)
内嵌无效连载(归档和放大器; AR,ORROctree ::节点::数据D,const的无符号整型版)

和应该已经阅读

 内嵌无效连载(归档和放大器; AR,ORROctree ::节点放; N,const的无符号整型版)
内嵌无效连载(归档和放大器; AR,ORROctree ::节点::数据和D,const的无符号整型版)

I am trying to serialize a class member. The following snippet of code will show the relevant class definitions and the non-intrusive serialization code I have included. I am getting a segfault during my saveHashTable() method which tries to serialize the class member shash_table_. Here is a self-contained trimmed version of the code:

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

解决方案

You just need to initialize the data in your data structures. All primitive types that haven't been explicitely initialized will have indeterminate ("random") values. This includes the pointers, which means you're invoking Undefined Behaviour by dereferencing pointers to random memory locations.

Here's an update with the simplest initialization that could possibly work, and it runs clean under Valgrind. That's a good tool. Use it!

Also, crank up the compiler messages (-Wall -Wextra -pedantic at a minimum for gcc/clang).

Added in various places:

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) 
{ }

See it Live On Coliru

Update From the comment: the following lines were clearly in error:

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)

And should have read

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)

这篇关于升压序列化段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆