空间配置器allocator
来源:互联网 发布:喜欢用数据说话的女人 编辑:程序博客网 时间:2024/05/16 09:55
1、 什么是空间配置器
在我看来就是STL容器后面默默工作进行内存管理和分配以及回收的的一个组件,为什么不叫内存配置器?STL源码剖析里说到:
因为空间不一定是内存,空间也可以是磁盘或其他辅助的存储介质。
2、空间配置器的标准接口有哪些
- allocator::value_type
- allocator::pointor
- allocator::const_pointer
- allocator::reference
- allocator::const_reference
- allocator::size_type
- allocator::difference_type
- allocator::rebind 一个嵌套的class template
- allocator::allocator()
- allocator::allocator(allocator&)
- allocator::~allocator()
- template allocator::allocator(const allocator&)
- pointer allocator::address(reference x) const
- const_pointer allocator::address(const_reference x) const
- pointer allocator::allocate(size_type n, const void* = 0)
- void allocator::deallocate(pointer p, size_type n)
- size_type allocator::max_size() const
- void allocator::construct(pointer p, const T& x) == new((void*)p) T(x)
- void allocator::destroy(pointer p) == p->~T()
3、实现一个简单的空间配置器
#ifndef CALLOCATOR_H#define CALLOCATOR_H#include <new>#include <cstddef>#include <cstdlib>#include <climits>#include <iostream>template <class T>class CAllocator{ 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 CAllocator<U> other; }; pointer allocate(size_type n, const void* hint = 0) { return (pointer)(::operator new(n * sizeof(T))); } void deallocate(pointer p, size_type n){ ::operator delete(p); } void construct(pointer p, const T& x) { new(p) T(x);} void destroy(pointer p) { p->~T(); } pointer address(reference x) {return (pointer)&x; } size_type max_size() const { return size_type(UINT_MAX / sizeof(T)); } const_pointer const_address(const_pointer x){ return (const_pointer)&x; } CAllocator(){}; ~CAllocator(){}; protected: private:};#endif // CALLOCATOR_H
#include <iostream>#include "CAllocator.h"#include <vector>int main(){ int a[5] = {0,1,2,3,4}; std::vector<int, CAllocator<int> > av(a, a+5); for(auto i: av) std::cout << i << ' '; std::cout << std::endl; return 0;}
3、SGI STL的配置器与标准规范不同
SGI STL仍然提供了一个标准的配置接口,叫simple_alloc,而SGI STL的配置器叫alloc而非allocator,而且不接受任何参数,例如:
vector<int, std::allocator<int>> iv;vector<int, std::alloc> ic;
但是SGI STL里提供的配置器效率更加好!
4、一般C++的内存配置的操作和释放过程:
例如
class A{...};A* a = new A;delete a;
new的操作:
1. 调用::operator new 进行配置内存;
2. 调用A::A()进行构造;
delete的操作:
1. 调用A::~A()进行析构;
2. 调用::operator delete 进行内存释放;
而STL的空间配置器恰恰把这两阶段区分开来,
1. 内存的分配由alloc::allocate()负责
2. 内存的释放由alloc::deallocate()负责
3. 对象的构造由::construct()负责
4. 对象的析构由::destroy()负责
按照STL的标准
配置器应该定义于之中,而SGI内含两个文件
#include <stl_alloc.h> //负责内存的配置和释放#include <stl_construct.h> //负责对象的构造和析构#include <stl_uninitialized.h> //定义了一些填充函数
#include <new.h> //使用placement new template <class _T1, class _T2>inline void _Construct(_T1* __p, const _T2& __value) { new ((void*) __p) _T1(__value); //调用placement new;}template <class _T1>inline void _Construct(_T1* __p) { new ((void*) __p) _T1();}template <class _Tp>inline void _Destroy(_Tp* __pointer) { __pointer->~_Tp(); //调用对象的析构}//判断区间元素里是否有没有必要调用对象的析构函数template <class _ForwardIterator, class _Tp>inline void __destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*){ typedef typename __type_traits<_Tp>::has_trivial_destructor _Trivial_destructor; __destroy_aux(__first, __last, _Trivial_destructor());}//如果有必要就调用析构函数template <class _ForwardIterator>void__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type){ for ( ; __first != __last; ++__first) destroy(&*__first);}//没有必要就不调用析构函数,大大提升效率template <class _ForwardIterator> inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}template <class _ForwardIterator>inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { __destroy(__first, __last, __VALUE_TYPE(__first));}template <class _T1, class _T2>inline void construct(_T1* __p, const _T2& __value) { _Construct(__p, __value);}template <class _T1>inline void construct(_T1* __p) { _Construct(__p);}template <class _Tp>inline void destroy(_Tp* __pointer) { _Destroy(__pointer);}template <class _ForwardIterator>inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { _Destroy(__first, __last);}
空间的配置与释放
#ifdef __USE_MALLOC...typedef __malloc_alloc_template<0> malloc_alloc;typedef malloc_alloc alloc; //第一级配置器...#else...typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc;//第二级配置器#endif
为了使SGI配置器符合STL规格,又进行一次简单的封装:
template<class T, class Alloc>class simple_alloc{ public: static T* allocate(size_t n) { return 0 == n ? 0 : (T*)Alloc::allocate(n * sizeof(T)); } static T* allocate(void) { return (T*)Alloc::allocate(sizeof(T)); } static void deallocate(T *p, size_t n) { if(n != 0) Alloc::deallocate(p, n * sizeof(T)); } static coid deallocate(T *p) { Alloc::deallocate(p, sizeof(T)); }}
如何使用这个接口:
template <class T, class Alloc = alloc>class vector { protected: typedef simple_alloc<value_type, Alloc> data_allocator; ...}
SGI STL 第一级配置器
template<int inst>class __malloc_alloc_template{...};
其中:
1. allocate()直接使用malloc();
2. deallocate()直接使用free();
3. 模拟C++中的set_new_handler()以处理内存不足的情况
SGI STL 第二级配置器
template <bool threads, int inst>class __default_alloc_template{...};
其中:
1. 维护16个自由链表,负责16种小型区块的次配置能力,内存池以malloc()配置而得。如果内存不足,转调用第一级配置器。
2. 如果需求区块大于128bytes,就调用第一级配置器
0 0
- 空间配置器allocator
- 空间配置器allocator
- STL:allocator空间配置器
- 一个简单的空间配置器: allocator
- STL之空间配置器allocator
- 【STL】SGI空间配置器 Allocator
- stl之空间配置器Allocator
- STL(一):allocator 空间配置器
- Chapter 2:空间配置器 allocator
- STL-空间配置器(allocator)
- STL 空间配置器 allocator<一>
- SGI STL 空间配置器(allocator)源码剖析
- 设计一个简单的空间配置器, JJ::allocator
- STL源码学习之空间配置器allocator【2013.11.15】
- 标准模板库的空间配置器 STL's allocator
- 标准模板库的空间配置器 STL allocator
- SGI STL 空间配置器(allocator)源码剖析
- c++实现一个简单的空间配置器allocator
- Codeforces Round #402 (Div. 2)B. Weird Rounding【暴力枚举】
- 485. Max Consecutive Ones
- 【Jmeter】——Update Statement & Callable Statement & Select Statement 分析
- EasyRTMP内置进入摄像机中实现网络推流直播摄像机的功能
- 理解 RESTful WebService
- 空间配置器allocator
- win7 64bit安装redis
- Codeforces Round #402 (Div. 2) A+B+C+D
- Error: Your project contains C++ files but it is not using a supported native build system
- java8个基本类型
- WireShark 4ICMP协议分析
- c++ primer plus 看后总结(一) c++特点与介绍
- SDR、DDR、QDR存储器的比较
- PAT甲级练习1061. Dating (20)