allocator必要接口:
allocator::value_type allocator::pointer allocator::const_pointer allocator::reference allocator::const_reference allocator::size_type allocator::difference_type
allocator::rebind
自定义allocator,书上说此空间配置其完全无法应用于SGI STL allocator,但是现在应该修改了,默认的空间配置器也是std::allocator
//2jjalloca.h
1 #ifndef _2JJALLOCA_H_ 2 #define _2JJALLOCA_H_ 3 4 #include <new> 5 #include <cstddef> 6 #include <cstdlib> 7 #include <climits> 8 #include <iostream> 9 10 using namespace std; 11 12 namespace JJ { 13 14 template<class T> 15 inline T* _allocate(ptrdiff_t size, T*) { 16 //set_new_handler(0);//不知道哪里的? 17 T* tmp = (T*) (::operator new((size_t) (size * sizeof(T)))); 18 //operator new可以被重载 19 if (tmp == 0) { 20 cerr << "out of memory" << endl; 21 exit(1); 22 } 23 return tmp; 24 } 25 26 template<class T> 27 inline void _deallocate(T* buffer) { 28 ::operator delete(buffer); 29 //operator delete可以被重载 30 // operator delete(buffer); 31 } 32 33 template<class T1, class T2> 34 inline void _construct(T1* p, const T2& value) { 35 new (p) T1(value); 36 } 37 38 template<class T> 39 inline void _destroy(T* ptr) { 40 ptr->~T(); 41 } 42 43 template<class T> 44 class allocator { 45 public: 46 typedef T value_type; 47 typedef T* pointer; 48 typedef const T* const_pointer; 49 typedef T& reference; 50 typedef const T& const_reference; 51 typedef size_t size_type; 52 typedef ptrdiff_t difference_type; 53 54 //rebind allocator of type U 55 template<class U> 56 struct rebind { 57 typedef allocator<U> other; 58 }; 59 60 //hint used for locality. ref.[Austern],p189 61 pointer allocate(size_type n, const void* hint = 0) { 62 return _allocate((difference_type) n, (pointer) 0); 63 } 64 65 void deallocate(pointer p, size_type n) { 66 _deallocate(p); 67 } 68 69 void construct(pointer p, const T& value) { 70 _construct(p, value); 71 } 72 73 void destroy(pointer p) { 74 _destroy(p); 75 } 76 77 pointer address(reference x) { 78 return (pointer) &x; 79 } 80 81 const_pointer const_address(const_reference x) { 82 return (const_pointer) &x; 83 } 84 85 size_type max_size() const { 86 return size_type(UINT_MAX / sizeof(T)); 87 } 88 89 }; 90 91 }//end of namespace JJ 92 93 #endif /* _2JJALLOCA_H_ */
//main.cpp
1 #include <iostream> 2 #include <vector> 3 #include "2jjalloca.h" 4 5 using namespace std; 6 7 int main(int argc, char **argv) { 8 int ia[5] = { 0, 1, 2, 3, 4 }; 9 unsigned int i; 10 fprintf(stderr, "ia addr:%p ", ia); 11 vector<int, JJ::allocator<int>> iv(ia, ia + 5); 12 for (i = 0; i < iv.size(); i++) { 13 cout << iv[i] << ' '; 14 } 15 cout << endl; 16 return 0; 17 }
运行结果也是正常的
================>现在由此引申出一个问题,operator new
1 #include <iostream> 2 #include <new> 3 #include <limits.h> 4 #include <stddef.h> 5 6 using namespace std; 7 8 template<class T> 9 inline T* allocate(ptrdiff_t size, T *) { 10 set_new_handler(0); 11 T* tmp = (T*) (::operator new((size_t) (size * sizeof(T)))); 12 if (tmp == 0) { 13 cerr << "out of memory" << endl; 14 exit(1); 15 } 16 return tmp; 17 } 18 19 template<class T> 20 inline void deallocate(T* buffer) { 21 ::operator delete(buffer); 22 } 23 24 template<class T> 25 class Allocator { 26 public: 27 typedef T value_type; 28 typedef T* pointer; 29 typedef const T* const_pointer; 30 typedef T& reference; 31 typedef const T& const_reference; 32 typedef size_t size_type; 33 typedef ptrdiff_t difference_type; 34 35 pointer allocate(size_type n) { 36 return ::allocate((difference_type) n, (T*) 0); 37 } 38 39 void deallocate(pointer p) { 40 ::deallocate(p); 41 } 42 43 pointer address(reference x) { 44 return (pointer) &x; 45 } 46 47 const_pointer const_address(const_reference x) { 48 return (const_pointer) &x; 49 } 50 51 size_type init_page_size() { 52 return max(size_type(1), size_type(4096 / sizeof(T))); 53 } 54 55 size_type max_size() const { 56 return max(size_type(1), size_type(UINT_MAX / sizeof(T))); 57 } 58 }; 59 60 template<> 61 class Allocator<void> { 62 public: 63 typedef void* pointer; 64 }; 65 66 int main(int argc, char **argv) { 67 68 return 0; 69 }
STL源码po析所说,SGI定义了一个有部分符合标准的allocator配置器(上面的代码),但是我看了自己本地的代码,似乎很符合标准呀。