Subject: Re: [Boost-bugs] [Boost C++ Libraries] #3080: dynamic_cast returns 0 on polymorphic serialization with weak_ptr
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-05-30 02:53:40
#3080: dynamic_cast returns 0 on polymorphic serialization with weak_ptr
----------------------------------------------------+-----------------------
Reporter: Takatoshi Kondo <kondo_at_[hidden]> | Owner: ramey
Type: Bugs | Status: new
Milestone: Boost 1.40.0 | Component: serialization
Version: Boost 1.39.0 | Severity: Problem
Resolution: | Keywords:
----------------------------------------------------+-----------------------
Comment(by Takatoshi Kondo <kondo_at_[hidden]>):
I'm sorry for being confused.
https://svn.boost.org/trac/boost/ticket/3080#comment:1 is not a sample
that works correctly.
The motivation of this sample is describe behavior of shared_ptr_hepler.
{{{
#!cpp
56 class shared_ptr_helper {
57 typedef std::map<const void *, shared_ptr<void> >
collection_type;
58 typedef collection_type::const_iterator iterator_type;
59 // list of shared_pointers create accessable by raw pointer.
This
60 // is used to "match up" shared pointers loaded at different
61 // points in the archive. Note, we delay construction until
62 // it is actually used since this is by default included as
63 // a "mix-in" even if shared_ptr isn't used.
64 collection_type * m_pointers;
snip ...
111 public:
112 template<class T>
113 void reset(shared_ptr<T> & s, T * r){
114 if(NULL == r){
115 s.reset();
116 return;
117 }
118 // get pointer to the most derived object. This is
effectively
119 // the object identifer
120 const void * od = object_identifier(r);
121
122 if(NULL == m_pointers)
123 m_pointers = new collection_type;
124
125 iterator_type it = m_pointers->find(od);
126
127 if(it == m_pointers->end()){
128 s.reset(r);
129 m_pointers->insert(collection_type::value_type(od,s));
130 }
131 else{
132 s = static_pointer_cast<T>((*it).second);
133 }
134 }
}}}
The sample that reproduces bug is the following.
https://svn.boost.org/trac/boost/attachment/ticket/3080/wps.cpp
And I made more essential following sample(sp_mlt_base.cpp).
{{{
#!cpp
#include <cassert>
#include <fstream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/weak_ptr.hpp>
struct Base1 {
virtual ~Base1() {}
// serialize
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & /*ar*/, const unsigned int /* file_version
*/) {}
};
BOOST_CLASS_EXPORT(Base1)
struct Base2 {
virtual ~Base2() {}
// serialize
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & /*ar*/, const unsigned int /* file_version
*/) {}
};
BOOST_CLASS_EXPORT(Base2)
struct Sub:public Base1, public Base2 {
virtual ~Sub() {}
boost::weak_ptr<Sub> wp_;
// serialize
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int /* file_version */)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
ar & BOOST_SERIALIZATION_NVP(wp_); // *1
}
};
BOOST_CLASS_EXPORT(Sub)
int main()
{
{
// serialize
boost::shared_ptr<Sub> s(new Sub);
boost::shared_ptr<Base2> pb2(s);
s->wp_ = s; // set weak_ptr. If not set, deserialize success.
std::ofstream ofs("output.xml");
assert(ofs);
boost::archive::xml_oarchive oa(ofs);
oa << boost::serialization::make_nvp("Base2", pb2);
}
{
// de-serialize
std::ifstream ifs("output.xml");
assert(ifs);
boost::archive::xml_iarchive ia(ifs);
boost::shared_ptr<Base2> pb2;
ia >> boost::serialization::make_nvp("Base2", pb2);
// check
// pb2's vptr is broken.
assert(dynamic_cast<Sub *>(pb2.get()));
}
}
}}}
Please check it.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3080#comment:4> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:00 UTC