【2014-06-18】C++ STL读书笔记:allocator

📅 2026/8/7 3:28:58
【2014-06-18】C++ STL读书笔记:allocator
[历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2014-06-18 标题C STL读书笔记allocator分类编程 / C C / C STL 标签CC·stl·allocatorC STL读书笔记allocator备注std::allocatornew\_allocator.h备注本读书笔记基于侯捷先生的《STL源码剖析》截图和注释版权均属于原作者所有。本读书笔记中的源码部分直接拷贝自SGI-STL部分代码删除了头部的版权注释但代码版权属于原作者。小弟初看stl很多代码都不是太懂注释可能有很多错误还请路过的各位大牛多多给予指导。std::allocator我们以vector为例子看下它的默认的allocator是什么。我们首先看下 vector 里面什么也没有但是有一行#includebits/stl_vector.h然后我们再看下 stl_vector.h 部分内容如下templatetypename_Tp,typename_Allocstd::allocator_Tpclassvector:protected_Vector_base_Tp,_Alloc。。。。。通过这个我们可以知道vector默认的allocator是std::allocator也可以大致的推断出其他的容器应该也是这个。我们打开 allocator.h 部分内容如下// Define the base class to std::allocator.#includebits/callocator.h_GLIBCXX_BEGIN_NAMESPACE(std)templatetypename_Tpclassallocator:public__glibcxx_base_allocator_Tp。。。。通过这里我们可以知道std::allocator就在这个文件中继承自【 __glibcxx_base_allocator 】。这里我们先跳过这个文件继续include。我们打开 callocator.h 部分内容如下#includeext/new_allocator.h#define__glibcxx_base_allocator__gnu_cxx::new_allocator这里我们知道【 __glibcxx_base_allocator 】其实就是【 __gnu_cxx::new_allocator 】继续打开 new_allocator.h 部分内容如下_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)templatetypename_Tpclassnew_allocator{。。。。。看到这里我们就可以大致的知道stl中的默认allocator的继承关系和代码位置了。然后我们开始注释代码去掉了头部版权注释new_allocator.h#includenew#includebits/functexcept.h#includebits/move.h//在命名空间__gnu_cxx中_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)usingstd::size_t;usingstd::ptrdiff_t;/** * brief An allocator that uses global new, as per [20.4]. * ingroup allocators * * This is precisely the allocator defined in the C Standard. * - all allocation calls operator new * - all deallocation calls operator delete *///《STL源码剖析》P43页对此作了简要介绍根据C标准如下typedef和函数是必须定义的。templatetypename_Tpclassnew_allocator{public:typedefsize_t size_type;typedefptrdiff_t difference_type;typedef_Tp*pointer;typedefconst_Tp*const_pointer;typedef_Tpreference;typedefconst_Tpconst_reference;typedef_Tp value_type;templatetypename_Tp1structrebind{typedefnew_allocator_Tp1other;};new_allocator()throw(){}new_allocator(constnew_allocator)throw(){}templatetypename_Tp1new_allocator(constnew_allocator_Tp1)throw(){}~new_allocator()throw(){}pointeraddress(reference __x)const{return__x;}const_pointeraddress(const_reference __x)const{return__x;}// NB: __n is permitted to be 0. The C standard says nothing// about what the return value is when __n 0.pointerallocate(size_type __n,constvoid*0){if(__nthis-max_size())std::__throw_bad_alloc();//申请空间时直接调用operator new,也就是我们平常使用的new操作符申请空间returnstatic_cast_Tp*(::operatornew(__n*sizeof(_Tp)));}// __p is not permitted to be a null pointer.voiddeallocate(pointer __p,size_type){::operatordelete(__p);}//申请空间时直接调用operator delete,也就是我们平常使用的delete操作符释放空间size_typemax_size()constthrow(){returnsize_t(-1)/sizeof(_Tp);}// _GLIBCXX_RESOLVE_LIB_DEFECTS// 402. wrong new expression in allocator::constructvoidconstruct(pointer __p,const_Tp__val){::new((void*)__p)_Tp(__val);}//调用placement new相当于在已有内存上直接调用构造函数#ifdef__GXX_EXPERIMENTAL_CXX0X__templatetypename..._Argsvoidconstruct(pointer __p,_Args...__args){::new((void*)__p)_Tp(std::forward_Args(__args)...);}#endifvoiddestroy(pointer __p){__p-~_Tp();}//直接调用实例的析构函数};templatetypename_Tpinlinebooloperator(constnew_allocator_Tp,constnew_allocator_Tp){returntrue;}templatetypename_Tpinlinebooloperator!(constnew_allocator_Tp,constnew_allocator_Tp){returnfalse;}_GLIBCXX_END_NAMESPACE