STL内存分配器--allocator

  • 一、STL内存分配器
  • 二、STL allocator

一、STL内存分配器

分配器(allocator))是C ++标准库的一个组件, 主要用来处理所有给定容器(vector,list,map等)内存的分配和释放。C ++标准库提供了默认使用的通用分配器std::allocator,但开发者可以自定义分配器。
GNU STL除了提供默认分配器,还提供了__pool_alloc、__mt_alloc、array_allocator、malloc_allocator 内存分配器。
__pool_alloc :SGI内存池分配器
__mt_alloc : 多线程内存池分配器
array_allocator : 全局内存分配,只分配不释放,交给系统来释放
malloc_allocator :堆std::malloc和std::free进行的封装

二、STL allocator

1、STL allocator简介
new会分配内存并执行对象构造函数,delete会执行对象析构函数并释放内存。如果将内存分配和对象构造分离,可以先分配大块内存,只在需要时才真正执行对象构造函数。
STL在头文件memory中提供了一个allocator类,允许将分配和对象构造分离,提供更好的性能和更灵活的内存管理能力。为了定义一个allocator对象,必须指明allocator可以分配的对象类型。当allocator分配内存时,会根据给定的对象类型来确定恰当的内存大小和对齐位置。

  template<typename _Tp>class allocator : public __allocator_base<_Tp>{public:typedef size_t     size_type;typedef ptrdiff_t  difference_type;typedef _Tp*       pointer;typedef const _Tp* const_pointer;typedef _Tp&       reference;typedef const _Tp& const_reference;typedef _Tp        value_type;template<typename _Tp1>struct rebind{ typedef allocator<_Tp1> other; };allocator() throw() { }allocator(const allocator& __a) throw(): __allocator_base<_Tp>(__a) { }template<typename _Tp1>allocator(const allocator<_Tp1>&) throw() { }~allocator() throw() { }// Inherit everything else.};

根据C++标准规范,STL中分配器的对外接口、成员变量都一样,只是接口内部实现有区别。
allocator实现在模板类new_allocator中:

  template<typename _Tp>class new_allocator{public:typedef size_t     size_type;typedef ptrdiff_t  difference_type;typedef _Tp*       pointer;typedef const _Tp* const_pointer;typedef _Tp&       reference;typedef const _Tp& const_reference;typedef _Tp        value_type;template<typename _Tp1>struct rebind{ typedef new_allocator<_Tp1> other; };new_allocator() _GLIBCXX_USE_NOEXCEPT { }new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }template<typename _Tp1>new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }~new_allocator() _GLIBCXX_USE_NOEXCEPT { }pointeraddress(reference __x) const _GLIBCXX_NOEXCEPT{ return std::__addressof(__x); }const_pointeraddress(const_reference __x) const _GLIBCXX_NOEXCEPT{ return std::__addressof(__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, const void* = static_cast<const void*>(0)){if (__n > this->max_size())std::__throw_bad_alloc();return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));}// __p is not permitted to be a null pointer.voiddeallocate(pointer __p, size_type){::operator delete(__p);}size_typemax_size() const _GLIBCXX_USE_NOEXCEPT{ return size_t(-1) / sizeof(_Tp); }#if __cplusplus >= 201103Ltemplate<typename _Up, typename... _Args>voidconstruct(_Up* __p, _Args&&... __args){ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }template<typename _Up>voiddestroy(_Up* __p) { __p->~_Up(); }
#else// _GLIBCXX_RESOLVE_LIB_DEFECTS// 402. wrong new expression in [some_] allocator::constructvoidconstruct(pointer __p, const _Tp& __val){ ::new((void *)__p) _Tp(__val); }voiddestroy(pointer __p) { __p->~_Tp(); }
#endif};template<typename _Tp>inline booloperator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&){ return true; }template<typename _Tp>inline booloperator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&){ return false; }_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

STL中容器默认分配器为std::allocator<_Tp>,内存分配和释放的接口allocate和deallocate内部实现只是将::operator new和::operator delete进行封装,没用做特殊处理。

3、STL allocator实例

4、自定义allocator
实现Allocator只需要实现allocate和deallocate,来实现自己的内存分配策略。

template<class T >
inline T*_allocate(ptrdiff_t num,T*){std::cout<<"_allocate"<<endl;return static_cast<T*>(::operator new(num*sizeof(T)));
}
template <class T>
inline void _deallocate(T* buff){std::cout<<"_deallocate"<<endl;::operator delete(buff);
}template <class T ,class U>
inline void _construct(T* p,const U& value){new(p)T(value);
}
template<class T>
inline void _destory(T* p){p->~T();
}
template<typename T>
class MyAlloctor{public:typedef T        value_type;typedef T*       pointer;typedef T&       reference;typedef const T* const_pointer;typedef const T& const_reference;typedef size_t     size_type;typedef ptrdiff_t  difference_type;template<typename _Tp1>struct rebind{ typedef MyAlloctor<_Tp1> other; };MyAlloctor()=default;~MyAlloctor()=default;pointer address(reference x){return static_cast<pointer>(&x);}const_pointer address(const_reference x){return static_cast<const_pointer>(&x);}pointer allocate(size_type _n,const void* hit=0 ){return _allocate(_n,(pointer)0);}void deallocate(pointer p,size_type _n){_deallocate(p);}size_type max_size()const throw(){return static_cast<size_type>(INT_MAX/sizeof(T));}void construct(pointer p,const_reference value){_construct(p,value);}void destroy(pointer p){_destory(p);}};

测试代码:

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
using namespace __gnu_cxx;//引入new_allocator
class base
{string name;int value;
public:base():name("test"),value(0) { cout << "base ctor" << endl; }explicit base(int v):name("explicit name"),value(v){cout<<"base ctor value="<<value<<endl;}virtual ~base() { cout << "base dtor" << endl; }base(const base& value) { cout << "Copy ctor" << endl; }base(base&& value) { cout << "move ctor" << endl; }void who(void){cout<<name<<" value= "<<value<<endl;}
};int main(void){new_allocator<base>alloc_test;
new_allocator<base>test;
base* p = alloc_test.allocate(3);cout<<"test1 start"<<endl;
cout<<"size of base="<<sizeof(base)<<endl;
cout<<"size of *p="<<sizeof(*p)<<endl;
p->who();
//(p+1)->who();
cout<<"test1 end\n"<<endl;
cout<<"test2 start"<<endl;
//test.construct(p,base(1));
//test.construct(p+1,base(2));
//test.construct(p+2,base(3));alloc_test.construct(p,base(1));
alloc_test.construct(p+1,base(2));
alloc_test.construct(p+2,base(3));p->who();
(p+1)->who();
(*p).who();
alloc_test.deallocate(p, 3);
getchar();
}
-----------------------------------
// output:
//todo
base dtor  //析构对象(仍然占有空间)
test deallocate//删除指针,释放空间。

C++: STL内存分配器--allocator相关推荐

  1. STL内存分配器:allocator

    一.STL泛型容器 与 内存管理 1.1 STL泛型容器中隐藏了内存管理工作 STL提供了很多泛型容器,如vector,list,map等.程序员使用时之关心如何存放对象,不用关心如何管理内存. 容器 ...

  2. 内存分配器ptmalloc,jemalloc,tcmalloc调研与对比

    内存分配器ptmalloc,jemalloc,tcmalloc调研与对比 rtoax 2020年12月 1. 概述 内存管理不外乎三个层面,用户程序层,C运行时库层,内核层.allocator 正是值 ...

  3. ptmalloc、tcmalloc与jemalloc内存分配器对比分析

    目录 背景介绍 ptmalloc 系统向看ptmalloc内存管理 用户向看ptmalloc内存管理 线程中内存管理 Chunk说明 tcmalloc 系统向看tcmalloc内存管理 用户向看tcm ...

  4. C++STL学习笔记(4) 分配器(Allocator)

    在前面的博客<C++ STL学习笔记(3) 分配器Allocator,OOP, GP简单介绍>中,简单的介绍了分配器再STL的容器中所担当的角色,这一节对STL六大部件之一的分配器进行详细 ...

  5. [转]STL的内存分配器

    题记:内存管理一直是C/C++程序的红灯区.关于内存管理的话题,大致有两类侧重点,一类是内存的正确使用,例如C++中new和delete应该成对出现,用RAII技巧管理内存资源,auto_ptr等方面 ...

  6. STL源码:分配器 allocator

    operator new() 和 malloc() operator new()就是调用malloc来申请内存空间 所有的分配内存操作最终都将落在 malloc 上.malloc分配的实际内存要比申请 ...

  7. 内存分配器 (Memory Allocator)

    对于大多数开发者而言,系统的内存分配就是一个黑盒子,就是几个API的调用.有你就给我,没有我就想别的办法.来UC前,我就是这样认为的.实际深入进去时,才发现这个领域里也是百家争鸣,非常热闹.有操作系统 ...

  8. 内存分配器(Memory Allocator)

    原文链接 : https://yq.aliyun.com/articles/254033 对于大多数开发者而言,系统的内存分配就是一个黑盒子,就是几个API的调用.有你就给我,没有我就想别的办法.来U ...

  9. Eigen内存分配器aligned_allocator

    在使用Eigen的时候,如果STL容器中的元素是Eigen数据库结构,比如下面用vector容器存储Eigen::Matrix4f类型或用map存储Eigen::Vector4f数据类型时: vect ...

最新文章

  1. 2017年计算机应用题库,2017年自学考试管理系统中计算机应用题库精选试题6
  2. RPC框架几行代码就够了
  3. JavaWeb黑马旅游网-学习笔记02【注册功能】
  4. wdns服务器未响应,Win7系统​网络诊断提示DNS服务器未响应的解决方法
  5. How is component metadata dependency dependencies consumed in the runtime
  6. what happened after a template is selected in Create with template button
  7. 简单而又不平凡的杨辉三角形
  8. Win10窗口侧边栏设置Win7模式
  9. redis list放入对象_Redis从入门到入土:详细讲解内存模型以及常用命令
  10. java编程测试题_Java编程测试可帮助您评估求职者
  11. C语言怎么实现熊猫上香中的系统错误提示,熊猫烧香的病毒是用什么程序语言编写的 原理是什么...
  12. php实现ts流切片,HLS-m3u8播放列表和ts切片(2)
  13. python爬虫做毕业设计_毕业设计之 --- 爬虫
  14. 新世纪大学英语(第二版)综合教程第一册 Unit 3 (中英翻译和重点单词)
  15. 蓝牙耳机的LDAC、aptX指的都是什么?
  16. TF实战丨使用Vagrant安装Tungsten Fabric
  17. 如何测试数字硅麦软件,硅麦参考电路及layout注意事项.PDF
  18. 课程学习(Curriculum Learning, CL)
  19. 《2022爱分析·营销服一体化实践报告》发布:营销服一体化重塑企业增长新链路
  20. 科技周刊第三期:人脸识别技术给我们带来的便利和风险

热门文章

  1. 实体间的联系存在着( )_【活动】迎新年送实体黑球+实况足球手游国服曼联精选抽黑视频!...
  2. requests手动添加cookies
  3. python获取软件窗口的坐标
  4. 德国商标“Black Friday”黑色星期五被取消
  5. 计算机电源整流滤波,开关电源设计:输入整流滤波器及钳位保护电路的设计
  6. java的三项表达式_Java三元表达式中的陷阱
  7. centos 7 重启php-fpm,centos7如何启动和重启php-fpm服务
  8. 第47集:如何扫除尘土飞扬的手指并保持编码状态
  9. C# 使用 PerformanceCounter 获取 CPU 和 硬盘的使用率
  10. 再刷网友修改版1.90.96WWE