|
Boost Users : |
From: Flogromp N. (looseonthestreet_at_[hidden])
Date: 2007-12-13 22:19:24
/*
The pool allocator is not being used properly, somehow, with std::list.
When you go to purge the pool, it says nothing was purged, because nothing
is even registered as being allocated in the pool.
What is going on here?
I have included copious debugging information. I've even provided a dummy
modification of the boost::pool_allocator class to show what's going on.
It's weird. If you change l_type to an std::vector, everything will work,
and the output will be: purged? 1
This program outputs the following when l_type is std::list,
debug_pool_allocator<Tag, T, UserAllocator, Mutex,
NextSize>::debug_pool_allocator() [with Tag = foo_tag, T = int,
UserAllocator = boost::default_user_allocator_new_delete, Mutex =
boost::details::pool::default_mutex, unsigned int NextSize = 32u]
debug_pool_allocator<Tag, T, UserAllocator, Mutex,
NextSize>::debug_pool_allocator(const debug_pool_allocator<Tag, U,
UserAllocator, Mutex, NextSize>&) [with U = int, Tag = foo_tag, T =
std::_List_node<int>, UserAllocator =
boost::default_user_allocator_new_delete, Mutex =
boost::details::pool::default_mutex, unsigned int NextSize = 32u]
static T* debug_pool_allocator<Tag, T, UserAllocator, Mutex,
NextSize>::allocate(typename boost::pool<UserAllocator>::size_type) [with
Tag = foo_tag, T = std::_List_node<int>, UserAllocator =
boost::default_user_allocator_new_delete, Mutex =
boost::details::pool::default_mutex, unsigned int NextSize = 32u]
--- static T* debug_pool_allocator<Tag, T, UserAllocator, Mutex, NextSize>::allocate(typename boost::pool<UserAllocator>::size_type) [with Tag = foo_tag, T = std::_List_node<int>, UserAllocator = boost::default_user_allocator_new_delete, Mutex = boost::details::pool::default_mutex, unsigned int NextSize = 32u] --- ... purged? 0 released? 0 This program outputs the following when l_type is std::vector, debug_pool_allocator<Tag, T, UserAllocator, Mutex, NextSize>::debug_pool_allocator() [with Tag = foo_tag, T = int, UserAllocator = boost::default_user_allocator_new_delete, Mutex = boost::details::pool::default_mutex, unsigned int NextSize = 32u] static T* debug_pool_allocator<Tag, T, UserAllocator, Mutex, NextSize>::allocate(typename boost::pool<UserAllocator>::size_type) [with Tag = foo_tag, T = int, UserAllocator = boost::default_user_allocator_new_delete, Mutex = boost::details::pool::default_mutex, unsigned int NextSize = 32u] --- static T* debug_pool_allocator<Tag, T, UserAllocator, Mutex, NextSize>::allocate(typename boost::pool<UserAllocator>::size_type) [with Tag = foo_tag, T = int, UserAllocator = boost::default_user_allocator_new_delete, Mutex = boost::details::pool::default_mutex, unsigned int NextSize = 32u] static void debug_pool_allocator<Tag, T, UserAllocator, Mutex, NextSize>::deallocate(T*, typename boost::pool<UserAllocator>::size_type) [with Tag = foo_tag, T = int, UserAllocator = boost::default_user_allocator_new_delete, Mutex = boost::details::pool::default_mutex, unsigned int NextSize = 32u] --- ... purged? 1 released? 0 */ #include <iostream> using std::cout; using std::endl; #include <list> #include <vector> #include <boost/current_function.hpp> #include <boost/limits.hpp> // std::numeric_limits #include <new> // std::bad_alloc #include <boost/pool/poolfwd.hpp> #include <boost/pool/singleton_pool.hpp> #include <boost/pool/pool_alloc.hpp> #define DEBUG_FUNC cout << BOOST_CURRENT_FUNCTION << " " << endl template < class Tag, class T, class UserAllocator = boost::default_user_allocator_new_delete, class Mutex = boost::details::pool::default_mutex, unsigned NextSize = 32 > class debug_pool_allocator { public: typedef T value_type; typedef UserAllocator user_allocator; typedef Mutex mutex; static unsigned const next_size = NextSize; typedef value_type* pointer; typedef value_type const* const_pointer; typedef value_type& reference; typedef value_type const& const_reference; typedef typename boost::pool<UserAllocator>::size_type size_type; typedef typename boost::pool<UserAllocator>::difference_type difference_type; template <class U> struct rebind { typedef debug_pool_allocator<Tag, U, UserAllocator, Mutex, NextSize> other; }; debug_pool_allocator() { DEBUG_FUNC; } // default copy constructor // default assignment operator // not explicit, mimicking std::allocator [20.4.1] template <class U> debug_pool_allocator( debug_pool_allocator<Tag, U, UserAllocator, Mutex, NextSize> const& ) { DEBUG_FUNC; } // default destructor static pointer address(reference r) { DEBUG_FUNC; return &r; } static const_pointer address(const_reference s) { DEBUG_FUNC; return &s; } static size_type max_size() { DEBUG_FUNC; return (std::numeric_limits<size_type>::max)(); } static void construct(pointer const ptr, value_type const& t) { DEBUG_FUNC; new(ptr) T(t); } static void destroy(pointer const ptr) { DEBUG_FUNC; ptr->~T(); } bool operator==(debug_pool_allocator const&) const { DEBUG_FUNC; return true; } bool operator!=(debug_pool_allocator const&) const { DEBUG_FUNC; return false; } static pointer allocate(size_type const n) { DEBUG_FUNC; const pointer ret = static_cast<pointer>( boost::singleton_pool< Tag, sizeof(T), UserAllocator, Mutex, NextSize >::ordered_malloc(n) ) ; if (ret == 0) throw std::bad_alloc(); return ret; } static pointer allocate(size_type const n, void const* const) { DEBUG_FUNC; return allocate(n); } static void deallocate(pointer const ptr, size_type const n) { DEBUG_FUNC; boost::singleton_pool< Tag, sizeof(T), UserAllocator, Mutex, NextSize >::ordered_free(ptr, n); } }; // --- struct foo_tag {}; // IF YOU CHANGE THIS TO std::vector, IT WILL DEALLOCATE PROPERLY! typedef std::list< int, debug_pool_allocator<foo_tag, int> > l_type; int main() { bool success = false; l_type* l = new l_type; for (int i=0; i<2; ++i) { l->push_back(444); cout << "---" << endl; } cout << "..." << endl; success = boost::singleton_pool<foo_tag, sizeof(int)>::purge_memory(); cout << "purged? " << success << endl; success = boost::singleton_pool<foo_tag, sizeof(int)>::release_memory(); cout << "released? " << success << endl; }
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net