C++ Boost序列化加载失败,引发异常

C++ Boost序列化加载失败,引发异常,c++,boost-serialization,C++,Boost Serialization,很长一段时间以来,我一直在努力使这项工作顺利进行 在我的项目中,通过实现模板函数serialize,有6个类正在使用boost提供的教程进行序列化 这些类是:State、guState、Policy、Action、Param、Vec3D 当我序列化并保存它们时,效果很好。我确实得到了一个文本文件,里面有各种数字和字符串 没有投诉,没有警告,没有引发异常。唯一的情况是,如果我尝试序列化一个类的指针成员,那么这个洞进程就会变成僵尸。因此,我不尝试这样做,并节省工程 当我尝试加载时,我得到: 在抛出的

很长一段时间以来,我一直在努力使这项工作顺利进行

在我的项目中,通过实现模板函数serialize,有6个类正在使用boost提供的教程进行序列化

这些类是:State、guState、Policy、Action、Param、Vec3D

当我序列化并保存它们时,效果很好。我确实得到了一个文本文件,里面有各种数字和字符串

没有投诉,没有警告,没有引发异常。唯一的情况是,如果我尝试序列化一个类的指针成员,那么这个洞进程就会变成僵尸。因此,我不尝试这样做,并节省工程

当我尝试加载时,我得到:

在抛出的实例后调用terminate 'boost::archive::archive\u异常'what():流错误

现在有趣的是,我序列化了两个boost::ptr_向量,一个由状态指针组成,另一个由策略指针组成

状态向量,我已保存并加载,没有问题。 策略向量,我可以保存,但当我尝试加载时,会出现异常

此外,在阅读了boost教程之后,我的印象是,为了加载,除了serialize函数之外,我不需要其他任何东西

然而,当我尝试加载时,boost序列化会抱怨没有找到默认构造函数,如State()、Policy()等(我在每个类中实现自己的构造函数)

阅读之后,我实现了一个默认构造函数,它什么也不做,这样boost序列化就可以工作了。事实上,它确实编译了,我得到了上面提到的结果

我试着沿着一条非常复杂的道路走下去,在那里我试着分离和实现save_construct_data和load_construct_data,但我发现这太难理解了,我再次得到了如上所述的确切错误

有人能帮我解释一下加载是如何工作的吗?默认构造函数的处理方法是什么?或者至少给我指出一个可能有用的链接。我已经阅读了boost中的手册,它们并没有对重建做太多解释

多谢各位

编辑(添加了几个片段)

类状态
{
好友类boost::serialization::access;
模板
无效序列化(存档&ar,常量未签名整数版本);
受保护的:
地图位置;
浮动奖励;
std::size\u t散列值;
bool存在(常量动作*A);
布尔运算符==(状态常数&S);
std::size_t hash();
无效清洁噪音();
State(){};//注意:这仅由序列化程序使用,没有它,代码将无法编译
公众:
枚举位置{站着,站在胸前,站在背后,站在左边,站在右边,站起来};
位置当前位置;
政策*我的政策;
矢量三维gps;
boost::ptr_向量动作;
状态(动作模式&m);
~State();
布尔运算符==(状态常量*S);
布尔运算符<(状态常量*S)常量;
常量float&getR()常量;
bool addAction(Action*A);
行动*findAction(持续行动*A);
boost::ptr_向量&getAllActions();
无效打印状态();
虚拟bool-isTerm();
};
模板
void State::serialize(存档&ar,常量unsigned int版本)
{
ar&BOOST\U序列化\U NVP(职位);
ar&BOOST__序列化_NVP(gps);
ar&BOOST\U序列化\U NVP(当前位置);
应收账款和增值税(奖励);
ar和BOOST_序列化_NVP(哈希值);
ar和BOOST_序列化_NVP(行动);
ar和BOOST_序列化_NVP(我的政策);
}
从State继承的其他类也有其序列化函数,使用:

  ar & boost::serialization::base_object<State>(*this);
ar&boost::serialization::base_对象(*this);
班级政策:

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

    Policy() {}; // NOTE: Again same as with state, used only by serialize load

  protected:

    float QValue;
    State *state;                

  public:

    //! Base class constructor 
    Policy(State *s);
    ...        
};

template <class Archive>
void Policy::serialize(Archive& ar, const unsigned int version)
{
  ar & BOOST_SERIALIZATION_NVP(action);
  ar & BOOST_SERIALIZATION_NVP(state);
  ar & BOOST_SERIALIZATION_NVP(QValue);
  ar & BOOST_SERIALIZATION_NVP(r);
}
类策略
{ 
好友类boost::serialization::access;
模板
无效序列化(存档&ar,常量未签名整数版本);
Policy(){};//注意:与state相同,仅由serialize load使用
受保护的:
浮点数;
国家*国家;
公众:
//!基类构造函数
政策(州政府);
...        
};
模板
void Policy::序列化(存档&ar,常量unsigned int版本)
{
ar&BOOST\U序列化\U NVP(行动);
ar&BOOST\U序列化\U NVP(州);
ar和BOOST_序列化_NVP(QValue);
ar&BOOST\U序列化\U NVP(r);
}
正如您所看到的,这是两个主要类,其他类也由于重构依赖关系(类操作、类参数等)而被序列化

硕士班:

template <class S, class P> class Task
{ 
  protected:
    ...
    //! Container of states of type S (template parameter)
    boost::ptr_vector<S> states;
    //! Container of policies of type P (template parameter)
    boost::ptr_vector<P> policies;
    ...

  public:

    Task(Agent &a, ACTION_MODE &m);
    ...
    void save_to_file();
    void load_from_file(std::string filename); 
};

template <class S, class P> 
void Task<S,P>::save_to_file()
{
  std::string output = ramdisk+"serialized";
  char *file = (char*)output.c_str();
  std::ofstream ofs(file);
  assert(ofs.good());  
  boost::archive::text_oarchive oa(ofs);
  oa << states;
  oa << policies;
  ofs.close();
}

template <class S, class P> 
void Task<S,P>::load_from_file(std::string filename)
{
  char *file = (char*)output.c_str();
  std::cout << file << std::endl;
  std::ifstream ifs(file);
  boost::archive::text_iarchive ia(ifs);
  ia >> states;
  ia >> policies;
  ifs.close();
}
模板类任务
{ 
受保护的:
...
//!S类型状态的容器(模板参数)
boost::ptr_矢量状态;
//!P类型策略的容器(模板参数)
boost::ptr_向量

策略; ... 公众: 任务(代理与a、行动与模式与m); ... 无效将_保存到_文件(); 无效从_文件加载_(std::string filename); }; 模板 无效任务::将_保存到_文件() { std::string output=ramdisk+“序列化”; char*file=(char*)output.c_str(); std::ofs流(文件); 断言(of s.good()); boost::archive::text\u oarchive oa(ofs); 办公自动化政策; ifs.close(); }

有效地包含两个保存状态和策略的boost::ptr_向量。 保存和加载状态时不会出现问题

加载策略时会出现问题。保存它们似乎不会产生问题(但我可能又错了)

在测试了不使用策略的保存/加载以及使用后,问题似乎在于策略重建

请注意,默认构造函数仅由序列化使用,没有这些构造函数,代码将无法编译


编辑#2:在使用valgrind和memcheck运行应用程序后,它报告存在指针内存泄漏。但是,由于我不擅长使用valgrind进行调试,我无法真正判断泄漏发生在何处,或者泄漏是否与我的序列化相关(我认为是)。问题在于,您正在序列化
状态
策略
Poli
template <class S, class P> class Task
{ 
  protected:
    ...
    //! Container of states of type S (template parameter)
    boost::ptr_vector<S> states;
    //! Container of policies of type P (template parameter)
    boost::ptr_vector<P> policies;
    ...

  public:

    Task(Agent &a, ACTION_MODE &m);
    ...
    void save_to_file();
    void load_from_file(std::string filename); 
};

template <class S, class P> 
void Task<S,P>::save_to_file()
{
  std::string output = ramdisk+"serialized";
  char *file = (char*)output.c_str();
  std::ofstream ofs(file);
  assert(ofs.good());  
  boost::archive::text_oarchive oa(ofs);
  oa << states;
  oa << policies;
  ofs.close();
}

template <class S, class P> 
void Task<S,P>::load_from_file(std::string filename)
{
  char *file = (char*)output.c_str();
  std::cout << file << std::endl;
  std::ifstream ifs(file);
  boost::archive::text_iarchive ia(ifs);
  ia >> states;
  ia >> policies;
  ifs.close();
}