积极答复者
关于自定义Allocator的问题?

问题
-
我想看一下STL容器类是如何管理其内存的,如何时分配、释放内存。于是我写了一个MyAllocator类,继承自std::allocator,所有的函数实现都是打印一行信息,然后调用相应的基类函数。代码如下:
#include <cstdio> #include <cstring> #include <string> #include <vector> #include <memory> template <typename T> class MyAllocator : public std::allocator<T> { typedef typename std::allocator<T> BaseType; typedef typename BaseType::size_type size_type; typedef typename BaseType::pointer pointer; public: MyAllocator() { printf( "MyAllocator Constructor.\n" );} MyAllocator( const MyAllocator &rhs ) {printf( "MyAllocator Copy Constructor.\n" );} ~MyAllocator() { printf( "MyAllocator Destructor.\n" );} pointer allocate( size_type _Count, const void* _Hint ) { printf( "MyAllocator::allocate() count = %u, hint = %x\n", _Count, _Hint ); return BaseType::allocate( _Count, _Hint ); } void deallocate( pointer _Ptr, size_type _Count ) { printf( "MyAllocator::deallocate() ptr = %x, count = %u\n", _Ptr, _Count ); BaseType::deallocate( _Ptr, _Count ); } void construct( pointer _Ptr, const T &_Val ) { printf( "MyAllocator::construct() ptr = %x\n", _Ptr ); BaseType::construct( _Ptr, _Val ); } void destroy( pointer _Ptr ) { printf( "MyAllocator::destroy() ptr = %x\n", _Ptr ); BaseType::destroy( _Ptr ); } }; struct Test { Test() { printf( "Test Constructor.\n" ); } Test( const Test &rhs ) { printf( "Test Copy Constructor.\n" ); } ~Test() { printf( "Test Destructor.\n" ); } int x; }; class MyString : public std::basic_string< char, std::char_traits<char>, MyAllocator<char> > { }; template <typename T> class MyVector : public std::vector< T, MyAllocator<T> > { }; int main() { // MyVector test { MyVector<int> vec; vec.reserve(100); vec.push_back(1); vec.push_back(2); printf( "%u, %u\n", vec.size(), vec.capacity() ); } // MyString test { MyString s; s.append("Hello, world!" ); } return 0; }
本想在调用MyVector的reserve或push_back函数时, MyAllocator的allocate函数会被调用,会看到其输出信息,但是事与愿违。程序运行结果如下:
MyAllocator Constructor. MyAllocator Copy Constructor. MyAllocator Destructor. MyAllocator Destructor. 2, 100
只有MyAllocator的构造和析构函数被调用,且都是因为MyVector的创建而引起,MyString虽然也指定了MyAllocator为其内存分配器,但并未引发MyAllocator的任何动作。
还有一点很奇怪,所有的MyAllocator对象都在调用reserve和push_back之前销毁了,似乎MyVector并未使用MyAllocator作为内存分配器。
这到底是什么原因呢???
答案
-
不需要从stl::alloctor派生。
template<class T> inline T* _allocate(ptrdiff_t size, T*) { T* tmp = static_cast<T*>(malloc(size * sizeof(T))); if ( tmp == 0 ) { exit(1); } return tmp; } template<class T> inline void _deallocate(T* buffer) { free(buffer); } template<class T1, class T2> inline void _construct(T1* p, const T2& value) { new(p) T1(value); } template<class T> inline void _destroy(T* ptr) { ptr->~T(); } template<class T> class MyAllocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template <class U> struct rebind { typedef MyAllocator<U> other; }; static pointer allocate( size_type n, const void* hint = 0) { return _allocate(static_cast<difference_type>(n), static_cast<pointer>(0)) ; } static void deallocate(void* p, size_type n) { _deallocate(p); } void construct(pointer p, const T& value) { _construct(p, value); } void destroy(pointer p) { _destroy(p); } pointer address(reference x) { return static_cast<pointer>(&x); } char *_Charalloc(size_type n) { return _allocate(static_cast<difference_type>(n), static_cast<char *>(0)) ; } const_pointer const_address(const_reference x) { return static_cast<const_pointer>(&x); } size_type max_size() const { return size_type(UINT_MAX/sizeof(T)); } public: MyAllocator(){}; virtual ~MyAllocator(){}; };
麻烦把正确答案设为解答。
- 已标记为答案 Charles_2013 2013年6月4日 8:45
- 取消答案标记 Charles_2013 2013年6月4日 8:47
- 已标记为答案 Charles_2013 2013年6月4日 8:47