Boost C++ Libraries: Ticket #8322: memory leak if load_construct_data throws https://svn.boost.org/trac10/ticket/8322 <p> tested with 1.46.1, but the problematic code is still there in trunk: </p> <p> there is a memory leak in the unlikely but possible situation that load_construct_data throws. </p> <p> the problem is at iserializer.hpp:326 (trunk) </p> <p> it uses a auto_ptr-like object to prevent a leak, but the auto_ptr is release()d on exception. here's a test case: </p> <pre class="wiki">#include &lt;boost/archive/text_oarchive.hpp&gt; #include &lt;boost/archive/text_iarchive.hpp&gt; #include &lt;fstream&gt; #include &lt;cassert&gt; using namespace boost; using namespace archive; struct type{ template&lt;class Archive&gt; void serialize(Archive &amp;ar,unsigned int version){} }; template&lt;class Archive&gt; void load_construct_data(Archive &amp;ar,type *t,unsigned int version){ throw 1; } int main(){ { type *t=new type; std::ofstream of("filename"); text_oarchive oa(of); oa &lt;&lt; t; delete t; } type *t=0; try{ std::ifstream if_("filename"); text_iarchive ia(if_); ia &gt;&gt; t; }catch(...){ //t is still 0, it's not my responsibility to delete: assert(t == 0); } } </pre><p> and here the output of valgrind --leak-check=full: </p> <pre class="wiki">==3062== HEAP SUMMARY: ==3062== in use at exit: 1 bytes in 1 blocks ==3062== total heap usage: 50 allocs, 49 frees, 18,590 bytes allocated ==3062== ==3062== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==3062== at 0x402B9B4: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3062== by 0x804E7EA: boost::archive::detail::heap_allocator&lt;type&gt;::doesnt_have_new_operator::invoke() (iserializer.hpp:253) ==3062== by 0x804E1DC: boost::archive::detail::heap_allocator&lt;type&gt;::invoke() (iserializer.hpp:263) ==3062== by 0x804DCDD: boost::archive::detail::pointer_iserializer&lt;boost::archive::text_iarchive, type&gt;::load_object_ptr(boost::archive::detail::basic_iarchive&amp;, void*&amp;, unsigned int) const (iserializer.hpp:305) ==3062== by 0x408476E: boost::archive::detail::basic_iarchive::load_pointer(void*&amp;, boost::archive::detail::basic_pointer_iserializer const*, boost::archive::detail::basic_pointer_iserializer const* (*)(boost::serialization::extended_type_info const&amp;)) (basic_iarchive.cpp:484) ==3062== by 0x804CE7F: void boost::archive::detail::load_pointer_type&lt;boost::archive::text_iarchive&gt;::invoke&lt;type*&gt;(boost::archive::text_iarchive&amp;, type*&amp;) (iserializer.hpp:524) ==3062== by 0x804CDCE: void boost::archive::load&lt;boost::archive::text_iarchive, type*&gt;(boost::archive::text_iarchive&amp;, type*&amp;) (iserializer.hpp:592) ==3062== by 0x804CD57: void boost::archive::detail::common_iarchive&lt;boost::archive::text_iarchive&gt;::load_override&lt;type*&gt;(type*&amp;, int) (common_iarchive.hpp:66) ==3062== by 0x804CD19: void boost::archive::basic_text_iarchive&lt;boost::archive::text_iarchive&gt;::load_override&lt;type*&gt;(type*&amp;, int) (basic_text_iarchive.hpp:65) ==3062== by 0x804CCD5: void boost::archive::text_iarchive_impl&lt;boost::archive::text_iarchive&gt;::load_override&lt;type*&gt;(type*&amp;, int) (text_iarchive.hpp:82) ==3062== by 0x804CB2D: boost::archive::text_iarchive&amp; boost::archive::detail::interface_iarchive&lt;boost::archive::text_iarchive&gt;::operator&gt;&gt;&lt;type*&gt;(type*&amp;) (interface_iarchive.hpp:60) ==3062== by 0x804C42C: main (test.cpp:32) ==3062== ==3062== LEAK SUMMARY: ==3062== definitely lost: 1 bytes in 1 blocks ==3062== indirectly lost: 0 bytes in 0 blocks ==3062== possibly lost: 0 bytes in 0 blocks ==3062== still reachable: 0 bytes in 0 blocks ==3062== suppressed: 0 bytes in 0 blocks </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8322 Trac 1.4.3 anonymous Thu, 21 Mar 2013 18:51:11 GMT <link>https://svn.boost.org/trac10/ticket/8322#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8322#comment:1</guid> <description> <p> it's actually correct that the auto_ptr-like object is release()d, because it doesn't only free the memory but also calls the destructor of "type", which would be invalid if load_construct_data throws, indicating it failed to construct. </p> <p> but there is still memory allocated that needs to be freed. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Wed, 21 Aug 2013 16:28:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8322#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8322#comment:2</guid> <description> <p> how about suggesting a patch? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Wed, 21 Aug 2013 16:57:30 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/8322#comment:3 https://svn.boost.org/trac10/ticket/8322#comment:3 <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">fixed</span> </li> </ul> <p> fixed - added deletion of memory to auto_ptr_with delete </p> Ticket