C++ 增压器故障
我正在尝试序列化一个类成员。下面的代码片段将显示相关的类定义和我包含的非侵入式序列化代码。我的saveHashTable()方法试图序列化类成员shash_table_时遇到一个segfault。以下是代码的自包含修剪版本:C++ 增压器故障,c++,boost,boost-serialization,C++,Boost,Boost Serialization,我正在尝试序列化一个类成员。下面的代码片段将显示相关的类定义和我包含的非侵入式序列化代码。我的saveHashTable()方法试图序列化类成员shash_table_时遇到一个segfault。以下是代码的自包含修剪版本: #include <map> #include <string> #include <vector> #include <set> #include <fstream> #include <boost/arc
#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();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
结构或八叉树
{
公众:
结构体类型
{
公众:
结构数据
{
公众:
浮点数n_u3;[3],p_3;[3];
int id_x_,id_y_,id_z_,lin_id_,num_points_;
std::设置邻居;
void*用户\数据\;
};
公众:
节点::数据*数据;
浮动中心[3],边界[6],半径[3];
节点*父节点\、*子节点\;
};
受保护的:
浮动体素大小,边界[6];
int-tree_-levels_uu;
节点*根;
std::矢量满叶;
};
结构模型库
{
模板
结构NDIMVoxelStructure
{
T*体素;
std::体素的向量总数;
std::体素的向量数;
体素的长总数;
向量界;
std::向量间距;
标准::向量最小中心;
};
双偶极子;
结构基{
偶极子seg1;
偶极子seg2;
};
typedef std::列表基础\u列表;
typedef std::映射表单元格;
//要序列化的成员
typedef NDIMVoxelStructure序列化哈希表;
公众:
序列化哈希表shash_table_u;
公众:
bool saveHashTable();
bool loadHashTable();
};
//用于形成SERIALIZEHASHTABLE的类型的序列化方法
名称空间提升{
命名空间序列化{
模板
内联void序列化(存档&ar,模型库::序列化哈希表&h,常量未签名int版本)
{
ar&h.体素总数;
ar&boost::serialization::make_数组(h.voxels_uu,h.total_num_uof_uvoxels_u);
体素的ar&h.num;
ar&h.体素总数;
ar&h;
ar&h;
ar&h.MINU中心;
}
模板
内联void序列化(存档&ar,模型库::Base&b,常量unsigned int版本)
{
ar&b.seg1;
ar&b.seg2;
}
模板
内联void序列化(存档&ar,ORROctree::节点n,常量unsigned int版本)
{
应收账款和应付账款数据;
ar&n中心;
应收账款和未收账款;
应收账款和应付账款;
应收账款和应付账款;
ar&n儿童基金会;
}
模板
内联void序列化(存档&ar,ORROctree::节点::数据d,常量无符号整数版本)
{
ar&d.id\u x\u;
ar&d.id\u y\u;
ar&d.id_z_;
研发部;
林先生;
ar&d.num_u点数u;
ar&d.p;
}
}
}
bool模型库::saveHashTable()
{
std::ofs流(“test.txt”);
boost::archive::text\u oarchive oa(ofs);
oa>shash_表;
返回true;
}
int main()
{
模型库m;
m、 saveHashTable();
}
您只需要初始化数据结构中的数据。所有未明确初始化的基元类型都将具有不确定(“随机”)值。这包括指针,这意味着您正在通过取消引用指向随机内存位置的指针来调用
这是一个最简单的初始化更新,它在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)
{ }
查看它
更新注释:以下几行明显有误:
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)
这个解决方案工作得很好,但我的实际代码遇到了一个不同的问题,它的类包含struct,但具有相同的继承权和数据成员。出于某种原因,正在从序列化函数调用Octree::Node的dtor,该函数将Octree::Node作为模板参数,并导致语句delete[]CHILDERS\上的segfault(dtor的一部分)。我不确定您是否可以在不查看代码的情况下帮助我,但我不明白为什么serliazer会调用Octree::Node的dtor。此外,segfault的stacktrace显示了600多个调用。当我使用valgrind运行它时,它没有崩溃,但它显示了一个无效的按大小读取8的问题,详细信息如下:如有任何见解,将不胜感激。我已经为此挣扎了好几个小时。我不能告诉你这些,因为你没有显示任何相关的代码(在你给出的代码中,没有一个析构函数,也没有删除)。无论如何,
ORROctree::Node::~Node
显然是被调用的,因为您在serialize
函数中按值传递它,这显然是一个错误(除此之外,最好检查所有类型的三个规则;同样,您没有显示所有代码,因此我无法帮助您)。我已经用缺少的两个&
修复了代码:在切线上,如果您能提出后续问题和新问题,我将不胜感激。