[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
construct and destroy never called in STL allocators
From: |
Gokhan Kisacikoglu |
Subject: |
construct and destroy never called in STL allocators |
Date: |
Fri, 28 May 2004 12:42:30 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030703 |
Hi,
I am using gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.2),
but I saw the same problems with the newer versions of gcc as well in
the stl containers.
I was trying to catch the construction and destruction of the actual
instances in my stl allocator for a given container. The allocate and
deallocate routines are always called, but all of the STL containers are
calling the global construct and destroy methods instead of the ones
defined in my allocator.
If this is not a bug, then I guess these two functions should be removed
from the standard conforming allocator interfaces (in stl_alloc.h),
because they are never used and very misleading for the users. I did
expect initially that they would be called instead of the global ones.
I attached a simple code for the std::map case, that I fixed by
specializing for the _Rb_tree_alloc_base template class for the
allocators with an instance. I had to make the construct and destroy
functions also templated, but I guess it could be worked out without
those, the intend here was just to demonstrate that the current
implementation does not call the construct and destroy for the user
defined allocators.
Thanks,
Gokhan
#include <map>
#include <typeinfo>
#include <iostream>
using namespace std;
template <typename _T>
class TypeAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _T* pointer;
typedef const _T* const_pointer;
typedef _T& reference;
typedef const _T& const_reference;
typedef _T value_type;
template <typename _T1> struct rebind
{
typedef TypeAllocator<_T1> other;
};
// ctor/dtors
//
TypeAllocator() {}
TypeAllocator(const TypeAllocator &_other) {}
template <typename _T1> TypeAllocator(const TypeAllocator <_T1> &_other) {}
TypeAllocator &operator = (const TypeAllocator&_other) { return *this; }
~TypeAllocator() {}
pointer address(reference _x) const { return &_x; }
const_pointer address(const_reference _x) const { return &_x; }
_T* allocate(size_type _n, const void* = 0)
{
return ((_n != 0) ?
static_cast <_T*> (base_alloc::allocate(_n * sizeof(_T))) : NULL);
}
void deallocate(pointer _p, size_type _n)
{
base_alloc::deallocate(_p, _n * sizeof(_T));
}
size_type max_size() const { return size_t(-1) / sizeof(_T); }
template <typename _T1> void construct(_T1* _p, const _T1 &_val)
{
cerr << "ctruct: " << typeid(*this).name() << endl;
new(_p) _T1(_val);
}
template <typename _T1> void destroy(_T1 *_p)
{
cerr << "dtruct: " << typeid(*this).name() << endl;
_p->~_T1();
}
private:
typedef std::alloc base_alloc; // The underlying allocator.
};
template<>
class TypeAllocator<void> {
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class _Tp1> struct rebind {
typedef TypeAllocator<_Tp1> other;
};
};
template <class _Tp, class _Alloc>
class _Rb_tree_alloc_base <_Tp, _Alloc, false> {
public:
typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
allocator_type get_allocator() const { return _M_node_allocator; }
_Rb_tree_alloc_base(const allocator_type& __a)
: _M_node_allocator(__a), _M_header(0) {}
protected:
typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type
_M_node_allocator;
_Rb_tree_node<_Tp>* _M_header;
_Rb_tree_node<_Tp>* _M_get_node()
{ return _M_node_allocator.allocate(1); }
void _M_put_node(_Rb_tree_node<_Tp>* __p)
{ _M_node_allocator.deallocate(__p, 1); }
void construct(_Tp *__p, const _Tp &_value)
{
_M_node_allocator.construct(__p, _value);
}
void destroy(_Tp *__p)
{
_M_node_allocator.destroy(__p);
}
};
typedef TypeAllocator <float> float_allocator;
typedef std::map <int, float, std::less <int>, float_allocator> IntMap;
typedef IntMap::key_compare map_key_compare;
typedef IntMap::value_type map_value_type;
int main(void)
{
IntMap mm;
mm = IntMap(map_key_compare(), float_allocator());
mm.insert(make_pair(10, 100.0f));
cerr << mm.find(10)->second << endl;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- construct and destroy never called in STL allocators,
Gokhan Kisacikoglu <=