Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86155 - in trunk/boost: archive archive/detail archive/impl archive/iterators serialization serialization/detail
From: ramey_at_[hidden]
Date: 2013-10-03 20:26:50


Author: ramey
Date: 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013)
New Revision: 86155
URL: http://svn.boost.org/trac/boost/changeset/86155

Log:
fixed memory leak on load_object_ptr and other changes

Text files modified:
   trunk/boost/archive/basic_text_oprimitive.hpp | 8 +++++
   trunk/boost/archive/binary_iarchive.hpp | 2
   trunk/boost/archive/detail/iserializer.hpp | 53 ++++++++++++++++++++++++++++++++++++---
   trunk/boost/archive/impl/basic_binary_iprimitive.ipp | 1
   trunk/boost/archive/impl/basic_binary_oprimitive.ipp | 1
   trunk/boost/archive/iterators/transform_width.hpp | 9 ++++++
   trunk/boost/serialization/detail/shared_count_132.hpp | 8 +++---
   trunk/boost/serialization/static_warning.hpp | 4 +-
   8 files changed, 72 insertions(+), 14 deletions(-)

Modified: trunk/boost/archive/basic_text_oprimitive.hpp
==============================================================================
--- trunk/boost/archive/basic_text_oprimitive.hpp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/archive/basic_text_oprimitive.hpp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -130,7 +130,13 @@
             boost::serialization::throw_exception(
                 archive_exception(archive_exception::output_stream_error)
             );
- os << std::setprecision(std::numeric_limits<float>::digits10 + 2);
+ // The formulae for the number of decimla digits required is given in
+ // http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf
+ // which is derived from Kahan's paper:
+ // http://http.cs.berkley.edu/~wkahan/ieee754status/ieee754.ps
+ unsigned int digits = std::numeric_limits<float>::digits * 3010;
+ digits /= 10000;
+ os << std::setprecision(digits);
         os << t;
     }
     void save(const double t)

Modified: trunk/boost/archive/binary_iarchive.hpp
==============================================================================
--- trunk/boost/archive/binary_iarchive.hpp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/archive/binary_iarchive.hpp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -29,7 +29,7 @@
 namespace archive {
 
 // do not derive from the classes below. If you want to extend this functionality
-// via inhertance, derived from text_iarchive_impl instead. This will
+// via inhertance, derived from binary_iarchive_impl instead. This will
 // preserve correct static polymorphism.
 
 // same as binary_iarchive below - without the shared_ptr_helper

Modified: trunk/boost/archive/detail/iserializer.hpp
==============================================================================
--- trunk/boost/archive/detail/iserializer.hpp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/archive/detail/iserializer.hpp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -238,21 +238,21 @@
     // boost::has_new_operator< T > doesn't work on these compilers
     #if DONT_USE_HAS_NEW_OPERATOR
         // This doesn't handle operator new overload for class T
- static T * invoke(){
+ static void * invoke(){
             return static_cast<T *>(operator new(sizeof(T)));
         }
     #else
         struct has_new_operator {
- static T* invoke() {
+ static void * invoke() {
                 return static_cast<T *>((T::operator new)(sizeof(T)));
             }
         };
         struct doesnt_have_new_operator {
- static T* invoke() {
+ static void * invoke() {
                 return static_cast<T *>(operator new(sizeof(T)));
             }
         };
- static T * invoke() {
+ static void * invoke() {
             typedef BOOST_DEDUCED_TYPENAME
                 mpl::eval_if<
                     boost::has_new_operator< T >,
@@ -288,7 +288,7 @@
 private:
     T* m_p;
 };
-
+#if 0
 // note: BOOST_DLLEXPORT is so that code for polymorphic class
 // serialized only through base class won't get optimized out
 template<class Archive, class T>
@@ -330,6 +330,49 @@
     ar_impl >> boost::serialization::make_nvp(NULL, * t);
     ap.release();
 }
+#endif
+// note: BOOST_DLLEXPORT is so that code for polymorphic class
+// serialized only through base class won't get optimized out
+template<class Archive, class T>
+BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr(
+ basic_iarchive & ar,
+ void * & t,
+ const unsigned int file_version
+) const
+{
+ Archive & ar_impl =
+ boost::serialization::smart_cast_reference<Archive &>(ar);
+
+ t = heap_allocator< T >::invoke();
+ if(NULL == t)
+ boost::serialization::throw_exception(std::bad_alloc()) ;
+
+ // catch exception during load_construct_data so that we don't
+ // automatically delete the t which is most likely not fully
+ // constructed
+ BOOST_TRY {
+ // this addresses an obscure situtation that occurs when
+ // load_constructor de-serializes something through a pointer.
+ ar.next_object_pointer(t);
+ boost::serialization::load_construct_data_adl<Archive, T>(
+ ar_impl,
+ static_cast<T *>(t),
+ file_version
+ );
+ }
+ BOOST_CATCH(...){
+ // don't destroy the object - because it was never really
+ // constructed.
+ //boost::serialization::access::destroy(t);
+ // just recover the memory
+ delete t;
+ t = NULL; // don't leave junk in t
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+
+ ar_impl >> boost::serialization::make_nvp(NULL, *static_cast<T *>(t));
+}
 
 template<class Archive, class T>
 pointer_iserializer<Archive, T>::pointer_iserializer() :

Modified: trunk/boost/archive/impl/basic_binary_iprimitive.ipp
==============================================================================
--- trunk/boost/archive/impl/basic_binary_iprimitive.ipp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/archive/impl/basic_binary_iprimitive.ipp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -28,6 +28,7 @@
 #include <boost/archive/archive_exception.hpp>
 #include <boost/archive/codecvt_null.hpp>
 #include <boost/archive/add_facet.hpp>
+#include <boost/archive/basic_binary_iprimitive.hpp>
 
 namespace boost {
 namespace archive {

Modified: trunk/boost/archive/impl/basic_binary_oprimitive.ipp
==============================================================================
--- trunk/boost/archive/impl/basic_binary_oprimitive.ipp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/archive/impl/basic_binary_oprimitive.ipp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -31,6 +31,7 @@
 
 #include <boost/archive/add_facet.hpp>
 #include <boost/archive/codecvt_null.hpp>
+#include <boost/archive/basic_binary_oprimitive.hpp>
 
 namespace boost {
 namespace archive {

Modified: trunk/boost/archive/iterators/transform_width.hpp
==============================================================================
--- trunk/boost/archive/iterators/transform_width.hpp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/archive/iterators/transform_width.hpp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -24,12 +24,15 @@
 // character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters
 // or 3 8 bit characters
 
+
 #include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME & PTFO
 #include <boost/serialization/pfto.hpp>
 
 #include <boost/iterator/iterator_adaptor.hpp>
 #include <boost/iterator/iterator_traits.hpp>
 
+#include <algorithm> // std::min
+
 namespace boost {
 namespace archive {
 namespace iterators {
@@ -112,6 +115,10 @@
     transform_width(BOOST_PFTO_WRAPPER(T) start) :
         super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast< T >(start)))),
         m_buffer_out_full(false),
+ // To disable GCC warning, but not truly necessary
+ //(m_buffer_in will be initialized later before being
+ //used because m_remaining_bits == 0)
+ m_buffer_in(0),
         m_remaining_bits(0),
         m_end_of_sequence(false)
     {}
@@ -119,8 +126,8 @@
     transform_width(const transform_width & rhs) :
         super_t(rhs.base_reference()),
         m_buffer_out_full(rhs.m_buffer_out_full),
- m_remaining_bits(rhs.m_remaining_bits),
         m_buffer_in(rhs.m_buffer_in),
+ m_remaining_bits(rhs.m_remaining_bits),
         m_end_of_sequence(false)
     {}
 };

Modified: trunk/boost/serialization/detail/shared_count_132.hpp
==============================================================================
--- trunk/boost/serialization/detail/shared_count_132.hpp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/serialization/detail/shared_count_132.hpp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -201,12 +201,12 @@
 
 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
-template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter< T > const &, int)
+template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &, int)
 {
     boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
 }
 
-template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter< T > const &, int)
+template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &, int)
 {
     boost::sp_array_constructor_hook(px);
 }
@@ -215,12 +215,12 @@
 {
 }
 
-template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter< T > const &, int)
+template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &, int)
 {
     boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
 }
 
-template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter< T > const &, int)
+template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &, int)
 {
     boost::sp_array_destructor_hook(px);
 }

Modified: trunk/boost/serialization/static_warning.hpp
==============================================================================
--- trunk/boost/serialization/static_warning.hpp Thu Oct 3 20:03:36 2013 (r86154)
+++ trunk/boost/serialization/static_warning.hpp 2013-10-03 20:26:49 EDT (Thu, 03 Oct 2013) (r86155)
@@ -72,6 +72,7 @@
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/print.hpp>
 #include <boost/mpl/eval_if.hpp>
+#include <boost/static_assert.hpp>
 
 namespace boost {
 namespace serialization {
@@ -101,8 +102,7 @@
 #define BOOST_SERIALIZATION_BSW(B, L) \
     typedef boost::serialization::BOOST_SERIALIZATION_SS< \
         sizeof( boost::serialization::static_warning_test< B, L > ) \
- > BOOST_JOIN(STATIC_WARNING_LINE, L);
-
+ > BOOST_JOIN(STATIC_WARNING_LINE, L) BOOST_STATIC_ASSERT_UNUSED_ATTRIBUTE;
 #define BOOST_STATIC_WARNING(B) BOOST_SERIALIZATION_BSW(B, __LINE__)
 
 #endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk