Boost C++ Libraries: Ticket #1942: Pointers to elements in a std::map are not serilaized correctly https://svn.boost.org/trac10/ticket/1942 <p> When serializing a std::map and some pointers that are referencing onto elements of that map, those pointers are not loaded correctly. </p> <p> Here's the code: </p> <pre class="wiki"> #include &lt;sstream&gt; #include &lt;boost/archive/text_oarchive.hpp&gt; #include &lt;boost/archive/text_iarchive.hpp&gt; #include &lt;boost/serialization/map.hpp&gt; struct dummy { template&lt;typename Archive&gt; void serialize(Archive &amp; ar, const unsigned int version) { } }; struct map_ref_test { std::map&lt;std::size_t, dummy&gt; m; dummy * ref; template&lt;typename Archive&gt; void serialize(Archive &amp; ar, const unsigned int version) { ar &amp; m; ar &amp; ref; } }; int main() { std::ostringstream os; map_ref_test m; m.m[0] = dummy(); m.m[1] = dummy(); m.m[2] = dummy(); m.ref = &amp;(m.m[1]); // serialize boost::archive::text_oarchive out(os); out &lt;&lt; const_cast&lt;map_ref_test const &amp;&gt;(m); // De-serialize map_ref_test m2; std::string ser = os.str(); std::istringstream is(ser); boost::archive::text_iarchive in(is); in &gt;&gt; m2; std::cout &lt;&lt; "0: " &lt;&lt; &amp;m.m[0] &lt;&lt; std::endl; std::cout &lt;&lt; "1: " &lt;&lt; &amp;m.m[1] &lt;&lt; std::endl; std::cout &lt;&lt; "2: " &lt;&lt; &amp;m.m[2] &lt;&lt; std::endl; std::cout &lt;&lt; "ref: " &lt;&lt; m.ref &lt;&lt; std::endl &lt;&lt; std::endl; std::cout &lt;&lt; "0: " &lt;&lt; &amp;m2.m[0] &lt;&lt; std::endl; std::cout &lt;&lt; "1: " &lt;&lt; &amp;m2.m[1] &lt;&lt; std::endl; std::cout &lt;&lt; "2: " &lt;&lt; &amp;m2.m[2] &lt;&lt; std::endl; std::cout &lt;&lt; "ref: " &lt;&lt; m2.ref &lt;&lt; std::endl; } </pre><p> This creates the following output: </p> <pre class="wiki">0: 0x805bfc4 1: 0x805bfe4 2: 0x805c004 ref: 0x805bfe4 0: 0x805ca04 1: 0x805ca24 2: 0x805ca44 ref: 0xbfacad5c </pre><p> I'd expect the last line to read: </p> <pre class="wiki">ref: 0x805ca24 </pre><p> The code works for std::vectors, so I'd assume it should work for maps also. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/1942 Trac 1.4.3 anonymous Wed, 28 May 2008 20:22:34 GMT <link>https://svn.boost.org/trac10/ticket/1942#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1942#comment:1</guid> <description> <p> We have the same problem. When an instance of ClassB is serialized, all the saved pointers in map are lost. </p> <p> We are using Boost 1.35.0 running on Fedora7(64 bits). gcc version 4.1.2 </p> <p> #include &lt;string&gt; #include &lt;map&gt; </p> <p> #include &lt;boost/serialization/serialization.hpp&gt; #include &lt;boost/serialization/access.hpp&gt; #include &lt;boost/serialization/is_abstract.hpp&gt; </p> <p> #include &lt;boost/serialization/base_object.hpp&gt; #include &lt;boost/serialization/extended_type_info_typeid.hpp&gt; #include &lt;boost/serialization/export.hpp&gt; </p> <p> #include &lt;boost/serialization/string.hpp&gt; </p> <p> #include &lt;boost/mpl/and.hpp&gt; #include &lt;boost/serialization/map.hpp&gt; </p> <p> using namespace std; using namespace boost::serialization; </p> <p> class A { </p> <blockquote> <p> friend class boost::serialization::access; template&lt;class Archive&gt; void serialize(Archive &amp; ar, const unsigned int version) { }; </p> </blockquote> <p> } </p> <p> class B : public A { private: </p> <blockquote> <p> friend class boost::serialization::access; template&lt;class Archive&gt; void serialize(Archive &amp; ar, const unsigned int version) { </p> <blockquote> <p> <em> serialize base class information ar &amp; boost::serialization::base_object&lt;A&gt;(*this); ar &amp; value; ar &amp; classACollection; </em></p> </blockquote> <p> } </p> </blockquote> <p> protected: </p> <blockquote> <p> long value; std::map&lt;long, ClassA * &gt; classACollection; </p> </blockquote> <p> public: </p> <blockquote> <p> A(); virtual ~A(); </p> </blockquote> <p> } BOOST_CLASS_EXPORT(B); </p> <p> class classA { private: </p> <blockquote> <p> friend class boost::serialization::access; template&lt;class Archive&gt; void serialize(Archive &amp; ar, const unsigned int version) { </p> <blockquote> <p> ar &amp; values; </p> </blockquote> <p> } </p> </blockquote> <p> protected: </p> <blockquote> <p> std::map &lt;long, ClassB *&gt; values; </p> </blockquote> <p> public: </p> <blockquote> <p> ClassA(); ClassA(ClassA &amp;object); virtual ~ClassA(); </p> </blockquote> <p> } </p> <p> class B { </p> <p> private: </p> <blockquote> <p> friend class boost::serialization::access; template&lt;class Archive&gt; void serialize(Archive &amp; ar, const unsigned int version) { </p> <blockquote> <p> ar &amp; value; </p> </blockquote> <p> } </p> </blockquote> <p> protected: </p> <blockquote> <p> string value; </p> </blockquote> <p> public: </p> <blockquote> <p> ClassB(); ClassB(ClassB &amp;object); virtual ~ClassB(); </p> </blockquote> <p> } </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Sun, 08 Jun 2008 20:49:29 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/1942#comment:2 https://svn.boost.org/trac10/ticket/1942#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> After a lot of work, I managed to discover what the problem is. </p> <p> The following case will fail when all three of the following are true: </p> <p> a) object is untracked (map&lt;&gt;::value_type in your case </p> <p> b) object contains something else that is tracked </p> <p> c) The containing object is moved after being deserialized - load a map has to do. </p> <p> In your case this can be address by adding: </p> <p> namespace boost { \ namespace serialization { \ template&lt;&gt; \ struct tracking_level&lt; std::map&lt;std::size_t, dummy&gt;::value_type &gt; \ { \ </p> <blockquote> <p> typedef mpl::integral_c_tag tag; \ typedef mpl::int_&lt; boost::serialization::track_always &gt; type; \ BOOST_STATIC_CONSTANT( \ </p> <blockquote> <p> int, \ value = tracking_level::type::value \ </p> </blockquote> <p> ); \ </p> </blockquote> <p> }; } } </p> <p> I haven't found any general solution. I'll add a note to the documentation. </p> <p> Robert Ramey </p> Ticket