Opened 9 years ago

Closed 8 years ago

#9567 closed Bugs (wontfix)

De-serialization of enable_shared_from_this through base class pointer fails

Reported by: Tim Regan Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.53.0 Severity: Problem
Keywords: serialization enable_shared_from_this shared_ptr weak_ptr Cc:

Description

Given the following class structure:

Base is a simple class. Derived inherits from Base. Derived also inherits from boost::enable_shared_from_this<Derived>. Base and Derived implement boost::serialization.

When deserializing an instance of Derived into a vector of boost::shared_ptr<Derived>:

Base and Derived members are reconstructed correctly. Derived::shared_from_this() works as expected.

But when deserializing an instance of Derived into a vector of boost::shared_ptr<Base>:

Base and Derived members are still reconstructed correctly. Derived::shared_from_this() throws a bad_weak_ptr exception. This is because enable_shared_from_this::weak_ptr is NOT reconstructed - It is zero.

See test code in attached file that demonstrates both of the above cases.

Attachments (3)

test_shared_from_this.cpp (4.8 KB ) - added by t_regan@… 9 years ago.
Test demonstrating enable_shared_from_this deserialization problem
test_shared_from_this.2.cpp (6.5 KB ) - added by t_regan@… 9 years ago.
Added test case to demonstrate workaround
test_enable_shared_from_this.cpp (5.3 KB ) - added by Robert Ramey 9 years ago.

Download all attachments as: .zip

Change History (7)

by t_regan@…, 9 years ago

Attachment: test_shared_from_this.cpp added

Test demonstrating enable_shared_from_this deserialization problem

comment:1 by t_regan@…, 9 years ago

Correction to original description: enable_shared_from_this::weak_this_::px is NOT reconstructed - It is zero.

comment:2 by t_regan@…, 9 years ago

Workaround: weak_this_ can be reconstructed by calling _internal_accept_owner (which fortunately is public) on each deserialized instance of Derived.

by t_regan@…, 9 years ago

Attachment: test_shared_from_this.2.cpp added

Added test case to demonstrate workaround

comment:3 by Robert Ramey, 9 years ago

I compiled and ran your example on my machine and have reproduced the problem.

Looking at your example, it seems to me that the serialization function of Derived should be:

	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
	       ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
               ar & boost::serialization::make_nvp(
                     enable_shared_from_this, 
                     boost::serialization::base_object<boost::enable_shared_from_this<Derived> >(*this) 
                )
		ar & BOOST_SERIALIZATION_NVP(m_derived);
         }

Of course this begs the question as to how serialization for boost::enable_shared_from_this<Derived> should be implemented. Of hand I don't remember what boost::enable_shared_from_this<Derived>does right now. ( could guess but I'm not going to waste your time). So my advice is to figure out how to implement serialization for boost::enable_shared_from_this<Derived> and re-submit.

maybe something like the following would work

	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
              boost_shared_ptr<Derived> m_sp = shared_from_this;
	       ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
	       ar & BOOST_SERIALIZATION_NVP(m_sp);
	       ar & BOOST_SERIALIZATION_NVP(m_derived);
         }

by Robert Ramey, 9 years ago

comment:4 by Robert Ramey, 8 years ago

Resolution: wontfix
Status: newclosed
Note: See TracTickets for help on using tickets.