boost :: archive :: binary_iarchive上的std :: bad_alloc

时间:2015-04-29 12:10:15

标签: c++ boost boost-serialization

我有上面的方法来序列化泛型类。

std::unique_ptr<Message> Serializer::deserialize(char* data , int size) {
    std::stringstream ss(std::ios_base::in |
                           std::ios_base::out |
                           std::ios_base::binary);
    ss.write( data, size );
    Message *in;

    boost::archive::binary_iarchive ia(ss, boost::archive::no_header);
    ia >> in;
    return  std::unique_ptr<Message> (in);
}

我得到了

 terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

当我尝试在char *上调用deserialize时,我确信它是整体发送的。 我尝试反序列化的类可以在这里找到:

class DiscoveryMessage : public Message {
public:

  DiscoveryMessage() {}

  DiscoveryMessage(int tcpPort);

  virtual ~DiscoveryMessage(){}

  friend class boost::serialization::access;

private:
  template <class Archive>
  void serialize(Archive &ar, const unsigned int ) {
    // invoke serialization of base class (Message)
    ar & boost::serialization::base_object<Message>(*this);
    ar & mTcpReceivePort;
    ar & mIPAddr;
  }

  int mTcpReceivePort;
  std::string mIPAddr;
};

1 个答案:

答案 0 :(得分:0)

确保您确实反序列化了序列化的相同类型。

具体来说,我看到你混合了unique_ptr和派生类。例如。您无法使用上述代码反序列化DiscoveryMessage*boost::shared_ptr<Message>等。

简单演示:

<强> Live On Coliru

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>

class DiscoveryMessage;
struct Message {
    virtual ~Message() {}

    virtual void do_print(std::ostream& os) const { os << "(base)"; }

    friend std::ostream& operator<<(std::ostream& os, Message const& m) {
        m.do_print(os);
        return os;
    }

    template <class Archive> void serialize(Archive &ar, const unsigned int) {
        ar.template register_type<DiscoveryMessage>();
    }
};

class DiscoveryMessage : public Message {
  public:
    DiscoveryMessage() {}

    DiscoveryMessage(int tcpPort) : mTcpReceivePort(tcpPort) {}
    virtual void do_print(std::ostream& os) const {
        os << "{" << mIPAddr << ":" << mTcpReceivePort << "}";
    }

  private:
    friend class boost::serialization::access;
    template <class Archive> void serialize(Archive &ar, const unsigned int) {
        // invoke serialization of base class (Message)
        ar & boost::serialization::base_object<Message>(*this);
        ar & mTcpReceivePort;
        ar & mIPAddr;
    }

    int mTcpReceivePort;
    std::string mIPAddr = "hello";
};

BOOST_CLASS_EXPORT(Message)
BOOST_CLASS_EXPORT(DiscoveryMessage)

#include <sstream>
#include <iostream>

int main()
{
    std::stringstream ss;
    {
        boost::archive::text_oarchive oa(ss);
        Message * p = new DiscoveryMessage(42);
        oa << p;
    }

    {
        boost::archive::text_iarchive ia(ss);
        Message * p;
        ia >> p;
        std::cout << *p << "\n";
    }
}

打印

{hello:42}