[Boost-bugs] [Boost C++ Libraries] #8977: Memory leak in boost::heap::fibonacci_heap when used with boost::shared_ptr and default allocator

Subject: [Boost-bugs] [Boost C++ Libraries] #8977: Memory leak in boost::heap::fibonacci_heap when used with boost::shared_ptr and default allocator
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-08-08 14:16:42


#8977: Memory leak in boost::heap::fibonacci_heap when used with boost::shared_ptr
and default allocator
------------------------------------------------+--------------------------
 Reporter: Wolf A. Heidrich <wolf.heidrich@…> | Owner: timblechmann
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: heap
  Version: Boost 1.54.0 | Severity: Problem
 Keywords: |
------------------------------------------------+--------------------------
 There is a bad possible memory leak in the fibonacci_heap when it is used
 with the default allocator and boost::shared_ptr.

 Example code:

 {{{
 #include <boost/heap/fibonacci_heap.hpp>
 #include <boost/shared_ptr.hpp>

 int main(int argc, char* argv[])
 {
     boost::heap::fibonacci_heap<boost::shared_ptr<int> > heap;
     heap.push(boost::shared_ptr<int>(new int(0)));

     return 0;
 }
 }}}

 Valgrind says:

 {{{
 ==8228== HEAP SUMMARY:
 ==8228== in use at exit: 28 bytes in 2 blocks
 ==8228== total heap usage: 650 allocs, 648 frees, 105,755 bytes
 allocated
 ==8228==
 ==8228== 28 (24 direct, 4 indirect) bytes in 1 blocks are definitely lost
 in loss record 2 of 2
 ==8228== at 0x4C2BCA7: operator new(unsigned long) (in
 /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
 ==8228== by 0x4080A3:
 boost::detail::shared_count::shared_count<int>(int*) (shared_count.hpp:91)
 ==8228== by 0x407E05: boost::shared_ptr<int>::shared_ptr<int>(int*)
 (shared_ptr.hpp:183)
 ==8228== by 0x40794D: main (SandBox.cpp:99)
 ==8228==
 ==8228== LEAK SUMMARY:
 ==8228== definitely lost: 24 bytes in 1 blocks
 ==8228== indirectly lost: 4 bytes in 1 blocks
 ==8228== possibly lost: 0 bytes in 0 blocks
 ==8228== still reachable: 0 bytes in 0 blocks
 ==8228== suppressed: 0 bytes in 0 blocks
 ==8228==
 ==8228== For counts of detected and suppressed errors, rerun with: -v
 ==8228== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)

 }}}

 The problem is the line

 {{{
 alloc_.deallocate(n, 1);
 }}}

 in the struct ''node_disposer'' in ''heap_node.hpp''.

 It does what it says: If it is a std::allocator which the
 boost::heap::allocator<> defaults to if not specified, it deallocates the
 memory but it does not call destructors as internally ''::operator
 delete()'' is called on the heap_node. That means that every object that
 has been pushed into the heap does not get its destructor called.

 Obviously this is really bad when using a boost::shared_ptr because the
 use_count will not go to 0. Using a boost::weak_ptr is not a remedy as the
 boost::shared_ptr's shared_count object that is on the heap will not get
 deleted as the boost::weak_ptr's destructor is not called and thus the
 boost::shared_ptr's weak_count does not go to 0.

 I did not check whether this problem affects the other heaps as well.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8977>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC