为什么需要allocator
整个stl的操作对象都是在容器中,而容易一定需要配置空间存放对象,我们通常使用容器的时候没有关心内存是如何分配的,者就是这篇文章要介绍的。
这是vector头文件的定义
template<
class T,
class Allocator = std::allocator<T>
> class vector;
可以看到在我们定义vector时,若没传allocator会使用默认的std::allocator,下面可以按照allocator的定义规范实现一个简单的空间配置器,空间可以是内存,共享内存、磁盘存储。
空间配置器的标准接口
根据STL的规范,allocator的必要接口
- 各种typedef
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind // class rebind<U>拥有唯一成员other;是一个typedef,代表allocator<U>
- 初始化,地址相关函数
// 配置空间,足以存储n个T对象,第二个参数是提示,能增进区域性
pointer allocator::allocate(size_type n, const void*=0)
size_type allocator::max_size() const
pointer allocator::address(reference x) const
const_pointer allocator::address(const_reference x) const
- 构建函数
void allocator::construct(pointer p, const T& x)
void allocator::destory(pointer p)
自定义allocator
定义allocator.h
#include <new>
#include <iostream>
#include <cstdlib> // for exit()
#include <climits> // for UNIX_MAX
#include <cstddef>
namespace test {
template<class T>
inline T* _allocate(ptrdiff_t size, T*) {
std::cout << "_allocate called" << std::endl;
set_new_handler(0);
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
if (NULL == tmp) {
std::cerr << "out of memory" << std::endl;
exit(0);
}
return tmp;
}
template<class T>
inline void _deallocate(T* p) {
::operator delete(p);
}
template<class T1, class T2>
inline void _construct(T1* p, const T2& value) {
::new(p) T1(value);
}
template<class T>
inline void _destroy(T* p) {
p->~T();
}
template<class T>
class Allocator
{
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 Allocator<U> other;
};
pointer allocate(size_type n, const void* hint=0) {
return _allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p, size_type n) {
return _deallocate(p);
}
void construct(pointer p, const T& value) {
_construct(p, value);
}
void destroy(pointer p) {
_destroy(p);
}
pointer address(reference x) {
return (pointer)&x;
}
const_pointer address(const_reference x) {
return (const_pointer)&x;
}
size_type max_size() const {
return size_type(UINT_MAX/sizeof(T));
}
};
} // end of namespace
在容器中使用上面自定义的allocator
#include "allocator.h"
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
cout << "allocator test" << endl;
vector<int, test::Allocator<int> > v;
v.push_back(1);
v.push_back(2);
for (int i = 0; i < v.size(); ++i)
{
cout << v[i] << endl;
}
return 0;
}
输出结果
allocator test
_allocate called
_allocate called
1
2