Re: boost::singleton_pool<...>::release_memory problem
On 7 10 , 8 44 , dasjotre <dasjo...@googlemail.com> wrote:
On 10 Jul, 03:37, Barry <dhb2...@gmail.com> wrote:
As boost::pool_alloc use singleton holder for pool allocator, client
programmers have to reclaim the memory by hand through calling
singleton_pool<alloc_tag, elem_size>::purge_memory() or something to
release the memory, so the program should have knowledge of the
elem_size, sometime, it's impossible or at least hard to know the size
of the element allocated by the allocator.
for example:
struct my_tag
list<int, boost::pool_allocator<int> > List;
....
boost::singleton_pool<boost::pool_allocator_tag,
sizeof(_List_node)>::release_memory()
Here _List_node is the real element that is dynamic created by
allocator, so if I use sizeof(int) instead, it does NOT work
indeed, list uses rebind mechanism to define allocator to use.
_List_node is implementation detail and you should not use it.
I don't think there is a way to achieve that other than to extend
pool_allocator
something like
template <class T, ...>
class my_pool_allocator : public boost::pool_allocator<T, ...>
{
.. forward constructors here
// rebind
template <typename U>
struct rebind
{
typedef my_pool_allocator<U, ...> other;
};
bool release_memory() const
{
return ::boost::singleton_pool
< ::boost::pool_allocator_tag
, sizeof(T)
...
>::release_memory();
}
};
std::list<int, my_pool_allocator<int, ...> > list;
list.get_allocator().release_memory()
regards
DS
As check out SGI and Dimkumware STL implementation, I found that they
neither rebind the XX_node(something like that) to be their
allocator_type, they separately provide _Buynod and _M_get_node to
create a node,
So the following code below in MSVC 8.0:
template <class T>
struct my_pool_allocator : pool_allocator<T> {
my_pool_allocator() : pool_allocator<T>() {}
my_pool_allocator(my_pool_allocator<T> const&) : pool_allocator<T>()
{}
my_pool_allocator(pool_allocator<T> const&) {}
template <class U>
struct rebind {
typedef my_pool_allocator<U> other;
};
static bool release_memory()
{
return singleton_pool
< pool_allocator_tag
, sizeof(T)
::release_memory();
}
};
int main(int argc, char* argv[])
{
typedef list<int, my_pool_allocator<int> > mylist;
mylist IntList;
cout << typeid(IntList.get_allocator()).name() << endl;
return 0;
}
produces the result:
struct my_pool_allocator<int>
and it really does not reclaim memory as I walk into the function
I don't konw the my_pool_allocator extension is right or not, but I
think it does not affect the result
So, if the container is not vector, it's hard to use
boost::pool_allocator and release_memory, if not hopeless
Thanks