STL Allocator空间分配器二

2024-01-25 08:38
文章标签 空间 stl 分配器 allocator

本文主要是介绍STL Allocator空间分配器二,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STL Allocator空间分配器二

 

今天把SGI提供的Allocator分配器仔细看了下,其设计还是相当精巧的。不过SGI的分配器已经脱离了STL标准,比如它就没有实现construct()destroy()成员函数。

 

简单malloc分配器

对于大于128B的空间直接就是malloc()free()了,没有什么特殊的;不过它还是仿造C++new handler形式设置了一个malloc exception handler;这样就和C++new行为相一致了,你可以设置malloc失败时的exception handler

 

Newdelete的分离

当对一个对象调用newdelete时,这两个操作都包含了两个阶段的动作:调用operator new分配空间,然后调用该对象的构造函数;调用该对象的析构函数,然后调用operator delete释放空间;SGI的分配器将这两步做了分离,内存分配和释放由函数alloc::allocate()alloc::deallocate()负责;物体构造和析构由函数construct()destroy()负责。

 

在调用destroy()函数同时释放n个对象(假设类型为T)时,SGI提供了方法可以判定对象是否有non-trivial destructor,如果没有则不必要循环为每个对象调用T::~T(),以提高效率,贴上源码,以便查看:

template <class T1, class T2>

inline void construct(T1* p, const T2& value) {

  new (p) T1(value);

}

template <class T>

inline void destroy(T* pointer) {

    pointer->~T();

}

template <class ForwardIterator>

inline void // 具有non trivial destructor

__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) {} //空函数体,trivial destructor不需要调用

template <class ForwardIterator, class T>

inline void __destroy(ForwardIterator first, ForwardIterator last, T*) {

  typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;

  __destroy_aux(first, last, trivial_destructor());

}

template <class ForwardIterator>

inline void destroy(ForwardIterator first, ForwardIterator last) {

  __destroy(first, last, value_type(first));

}

这需要借助于Traits编程技法来完成(原书3.7节)的:

typedef typename __type_traits<T>::has_trivial_destructor  trivial_destructor;

首先使用value_type()获取迭代器指向的物体类型,然后使用__type_traits<T>查看T是否有non-trivial destructor

 

简单分配器 simple_alloc

SGI为这原始分配器malloc和次级分配器alloc所作的一层简单封装;

 

次级分配器alloc

对于小于128B的请求采用了次级分配器;说白了就是SGI维护一个内存池来处理这些请求,以保证效率。它会将请求的字节数n圆整到8的倍数,比如如果请求的是14B的空间,其实获得的是16B;从这也可以得出SGI一共有16个链表需要维护,每个链表对应一个分配级别,对应的内存块大小分别是:81624128

为了不浪费存储空间,链表是一个union结构,像这样:

       union OBJ{

              union OBJ *free;

              char *data[1];

       };

free指针指向的是free链表中下一个空闲内存块,如果一个内存块被分配出去,就交给用户程序维护了,那么该块就没有必要继续维护了,知道再次收回(通过 free())。

分配和回收函数allocate()deallocate()就是简单的链表操作了,没有特别的地方。

比较复杂的就是内存池的维护函数chunk_alloc()函数,它最终还是需要通过malloc()来申请内存新的空间。

 

辅助函数

最后是几个操作为初始化空间的辅助函数,其内部基本都是通过调用全局construct()函数完成的。

 

对别人不是问题的问题

读到最后一直有个疑惑就是allocator没有实现construct()函数,那么它和容器是如何协同工作的呢?搜了搜源文件才发现,原来各容器都会显式调用全局函数construct()construct函数实际调用placement new),比如下面是list容器模板的一段代码:

 

typedef simple_alloc<list_node, Alloc> list_node_allocator;

link_type get_node() { return list_node_allocator::allocate(); }

void put_node(link_type p) { list_node_allocator::deallocate(p); }

  link_type create_node(const T& x) {

    link_type p = get_node();

    __STL_TRY {

      construct(&p->data, x);

    }

    __STL_UNWIND(put_node(p));

    return p;

  }

  void destroy_node(link_type p) {

    destroy(&p->data);

    put_node(p);

  }

 

这篇关于STL Allocator空间分配器二的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/642697

相关文章

关于MySQL将表中数据删除后多久空间会被释放出来

《关于MySQL将表中数据删除后多久空间会被释放出来》MySQL删除数据后,空间不会立即释放给操作系统,而是会被标记为“可重用”,以供未来插入新数据时使用,只有满足特定条件时,空间才可能真正返还给操作... 目录一、mysql数据删除与空间管理1.1 理解MySQL数据删除原理1.3 执行SQL1.3 使用

MySQL8.0临时表空间的使用及解读

《MySQL8.0临时表空间的使用及解读》MySQL8.0+引入会话级(temp_N.ibt)和全局(ibtmp1)InnoDB临时表空间,用于存储临时数据及事务日志,自动创建与回收,重启释放,管理高... 目录一、核心概念:为什么需要“临时表空间”?二、InnoDB 临时表空间的两种类型1. 会话级临时表

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

Ubuntu如何分配​​未使用的空间

《Ubuntu如何分配​​未使用的空间》Ubuntu磁盘空间不足,实际未分配空间8.2G因LVM卷组名称格式差异(双破折号误写)导致无法扩展,确认正确卷组名后,使用lvextend和resize2fs... 目录1:原因2:操作3:报错5:解决问题:确认卷组名称​6:再次操作7:验证扩展是否成功8:问题已解

MySQL之InnoDB存储页的独立表空间解读

《MySQL之InnoDB存储页的独立表空间解读》:本文主要介绍MySQL之InnoDB存储页的独立表空间,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、独立表空间【1】表空间大小【2】区【3】组【4】段【5】区的类型【6】XDES Entry区结构【

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

MySQL启动报错:InnoDB表空间丢失问题及解决方法

《MySQL启动报错:InnoDB表空间丢失问题及解决方法》在启动MySQL时,遇到了InnoDB:Tablespace5975wasnotfound,该错误表明MySQL在启动过程中无法找到指定的s... 目录mysql 启动报错:InnoDB 表空间丢失问题及解决方法错误分析解决方案1. 启用 inno

在Java中基于Geotools对PostGIS数据库的空间查询实践教程

《在Java中基于Geotools对PostGIS数据库的空间查询实践教程》本文将深入探讨这一实践,从连接配置到复杂空间查询操作,包括点查询、区域范围查询以及空间关系判断等,全方位展示如何在Java环... 目录前言一、相关技术背景介绍1、评价对象AOI2、数据处理流程二、对AOI空间范围查询实践1、空间查

MySQL表空间结构详解表空间到段页操作

《MySQL表空间结构详解表空间到段页操作》在MySQL架构和存储引擎专题中介绍了使用不同存储引擎创建表时生成的表空间数据文件,在本章节主要介绍使用InnoDB存储引擎创建表时生成的表空间数据文件,对... 目录️‍一、什么是表空间结构1.1 表空间与表空间文件的关系是什么?️‍二、用户数据在表空间中是怎么