serialization: curious un-serializing issue RFI
I have a curious problem that's just sprung up, after changing from using plain-old-pointers to using boost::shared_ptrs internally in my data structures (stl hash_map and map) The problem is that while the XML archive works correctly, both text and binary fail (they all used to work). This is using gcc 4.0.1 on darwin and VC8 on windows, boost version is 1.34.1 The failure occurs while unserializing an archive, specifically when trying to read back a shared_ptr to an already unserialized object. In the archive, it shows the object (pointer) as an object_reference (the same reference id in XML and text). While the XML version reads the pointer back correctly, the text version fails and returns NULL. I have not determined the exact reason why the text version fails (it doesn't throw, just returns NULL). The serialization does not appear to have any problems. Since my actual code is reasonably complicated, and I haven't created a simplified version that demonstrates the problem, I'm not including code now - I'd just like to find out if this sounds familiar to anyone, that is, working under XML but failing under text and binary. It does appear to be shared_ptr specific, too, since everything was working before replacing naked pointers with shared_ptrs.
more info: On Oct 27, 2007, at 3:36 PM, Hugh Hoover wrote:
I have a curious problem that's just sprung up, after changing from using plain-old-pointers to using boost::shared_ptrs internally in my data structures (stl hash_map and map) The problem is that while the XML archive works correctly, both text and binary fail (they all used to work).
This is using gcc 4.0.1 on darwin and VC8 on windows, boost version is 1.34.1
The failure occurs while unserializing an archive, specifically when trying to read back a shared_ptr to an already unserialized object. In the archive, it shows the object (pointer) as an object_reference (the same reference id in XML and text). While the XML version reads the pointer back correctly, the text version fails and returns NULL. I have not determined the exact reason why the text version fails (it doesn't throw, just returns NULL). The serialization does not appear to have any problems.
The proximate cause of the problem is in void_upcast, which does not find a pre-registered pair of types matching the base and derived types passed in from load_pointer_type::invoke. I'm having a hard time understanding how that could be... I've called void_cast_register for the type pair, so it SHOULD be registered - and the xml_iarchive was able to reconstruct the object properly. Any suggestions?
the package includs test_derived_class. How does your example differ from that one? RObert Ramey Hugh Hoover wrote:
more info:
On Oct 27, 2007, at 3:36 PM, Hugh Hoover wrote:
I have a curious problem that's just sprung up, after changing from using plain-old-pointers to using boost::shared_ptrs internally in my data structures (stl hash_map and map) The problem is that while the XML archive works correctly, both text and binary fail (they all used to work).
This is using gcc 4.0.1 on darwin and VC8 on windows, boost version is 1.34.1
The failure occurs while unserializing an archive, specifically when trying to read back a shared_ptr to an already unserialized object. In the archive, it shows the object (pointer) as an object_reference (the same reference id in XML and text). While the XML version reads the pointer back correctly, the text version fails and returns NULL. I have not determined the exact reason why the text version fails (it doesn't throw, just returns NULL). The serialization does not appear to have any problems.
The proximate cause of the problem is in void_upcast, which does not find a pre-registered pair of types matching the base and derived types passed in from load_pointer_type::invoke. I'm having a hard time understanding how that could be... I've called void_cast_register for the type pair, so it SHOULD be registered - and the xml_iarchive was able to reconstruct the object properly.
Any suggestions?
On Oct 29, 2007, at 7:16 PM, Robert Ramey wrote:
the package includs test_derived_class.
How does your example differ from that one?
good question... trivial differences: 5 element classes (1 abstract base+derived pair, 1 abstract base+2 derived) 2 collection classes - hash_map in both cases, but my own serializer (which eliminates a redundant key serialization in my cases) my serialization code is defined and instantiated in a .cpp file rather than in the headers. I'm using split_member for all classes. The function that attempts to load the object reference (the one that's failing) is in a load_construct_data and not a "normal" load function. most "interesting" difference so far: the save_construct_data is saving the reference through a const pointer, like: boost::smart_ptr<B const> b_ptr = this->m_b; ar << boost::serialization::make_nvp("b_ptr", b_ptr); while the load_construct_data unserializes with: boost::smart_ptr<B> b_ptr; ar >> boost::serialization::make_nvp("b_ptr", b_ptr); I'll try changing the save_construct_data to use a non-const pointer... If that doesn't work, I'll create a stripped down test and see if I can replicate the problem in some simpler test code.
I have a curious problem that's just sprung up, after changing from using plain-old-pointers to using boost::shared_ptrs internally in my data structures (stl hash_map and map) The problem is that while the XML archive works correctly, both text and binary fail (they all used to work).
This is using gcc 4.0.1 on darwin and VC8 on windows, boost version is 1.34.1
The failure occurs while unserializing an archive, specifically when trying to read back a shared_ptr to an already unserialized object. In the archive, it shows the object (pointer) as an object_reference (the same reference id in XML and text). While the XML version reads the pointer back correctly, the text version fails and returns NULL. I have not determined the exact reason why the text version fails (it doesn't throw, just returns NULL). The serialization does not appear to have any problems.
The proximate cause of the problem is in void_upcast, which does not find a pre-registered pair of types matching the base and derived types passed in from load_pointer_type::invoke. I'm having a hard time understanding how that could be... I've called void_cast_register for the type pair, so it SHOULD be registered - and the xml_iarchive was able to reconstruct the object properly.
Any suggestions?
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On Oct 30, 2007, at 9:18 AM, Hugh Hoover wrote:
most "interesting" difference so far: the save_construct_data is saving the reference through a const pointer, like:
boost::smart_ptr<B const> b_ptr = this->m_b; ar << boost::serialization::make_nvp("b_ptr", b_ptr);
while the load_construct_data unserializes with:
boost::smart_ptr<B> b_ptr; ar >> boost::serialization::make_nvp("b_ptr", b_ptr);
I'll try changing the save_construct_data to use a non-const pointer...
Well DAMN! I guess that makes sense - a pointer to const isn't the same as a pointer to non-const. At the time I (re)wrote the code it just made sense to me to use a const pointer... Actually - on looking at the older code, I was using a (c) pointer to const (like A const* a_ptr), in the save_construct_data and A * a_ptr in the load_construct_data. So, the change to using shared_ptr changed the behaviour of the serialization code... I'm not sure if shared_ptr should act exactly like a plain pointer in this case or not... In any case, thanks for the debugging tip :) I probably should have done that earlier.. Hugh Hoover Enumclaw Software And you probably already guessed that the code above is not quite right :) there's no "this" and it should be boost::shared_ptr<A>, not a "B" pointer.
participants (2)
-
Hugh Hoover
-
Robert Ramey