【C++学习】STL之空间配置器之一级空间配置器


📊什么是空间配置器

空间配置器,顾名思义就是为各个容器高效的管理空间(空间的申请与回收)的,在默默地工作。
在这里插入图片描述

✈STL 提供六大组件的了解

  • 容器(containers):各种数据结构,如 vector, list, deque, set, map 用来存放数据。从实现的角度来看,STL 容器是一种 class template。
  • 算法(algorithms):各种常用的算法如 sort, search, copy, erase…从实现角度来看,STL 算法是一种 function template。
  • 迭代器(iterators):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。从实现角度来看,迭代器是一种将 operator *, operator ->, operator++, operator– 等指针相关操作予以重载的class template。
  • 仿函数(functors):行为类似函数,可以作为算法的某种策略。从实现角度来看,仿函数是一种重载了 operator() 的 class 或class template。
  • 适配器(adapters):一种用来修饰容器或仿函数或迭代器接口的东西。例如 STL 提供的 queue 和 stack,虽然看似容器,其实只能算是一种容器适配器,因为它们的底部完全借助 deque,所有操作都由底层的 deque 供应。
  • 配置器(allocator):负责空间配置与管理,从实现角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的 class template。

在这里插入图片描述

👀为什么需要空间配置器

  • 从使用 STL 层面而言,空间配置器并不需要介绍 ,因为容器底层都给你包装好了,但若是从 STL 实现角度出发,空间配置器是首要理解的。

  • 作为 STL 设计背后的支撑,空间配置器总是在默默地付出着。为什么你可以使用算法来高效地处理数据,为什么你可以对容器进行各种操作,为什么你用迭代器可以遍历空间,这一切的一切,都有“空间配置器”的功劳。

模拟实现vector、list、map、unordered_map等容器时,所有需要空间的地方都是通过new申请的,虽然代码可以正常运行,但是有以下不足之处:

  • 空间申请与释放需要用户自己管理,容易造成内存泄漏。
  • 频繁向系统申请小块内存块,容易造成内存碎片。
  • 频繁向系统申请小块内存,影响程序运行效率。
  • 直接使用malloc与new进行申请,每块空间前有额外空间浪费。
  • 申请空间失败怎么应对。
  • 代码结构比较混乱,代码复用率不高。
  • 未考虑线程安全问题。

因此需要设计一块高效的内存管理机制。

👍SGI-STL空间配置器实现原理

以上提到的几点不足之处,最主要还是:频繁向系统申请小块内存造成的。那什么才算是小块内存?SGI-STL以128作为小块内存与大块内存的分界线,将空间配置器其分为两级结构,一级空间配置器处理大块内存,二级空间配置器处理小块内存。

🌂一级空间配置器的实现

  • 一级空间配置器原理非常简单,直接对malloc与free进行了封装,并增加了C++中
    set_new_handle思想。

实现代码:

template <int inst>
class __malloc_alloc_template
{
private:
 static void *oom_malloc(size_t);
public:
// 对malloc的封装
 static void * allocate(size_t n)
 {
   // 申请空间成功,直接返回,失败交由oom_malloc处理
 void *result = malloc(n);
 if (0 == result) 
   result = oom_malloc(n);
 return result;
 }
// 对free的封装
 static void deallocate(void *p, size_t /* n */)
 { free(p);}
 // 模拟set_new_handle
 // 该函数的参数为函数指针,返回值类型也为函数指针
 // void (*   set_malloc_handler( void (*f)() ) )()
 static void (* set_malloc_handler(void (*f)()))()
 {
 void (* old)() = __malloc_alloc_oom_handler;
 __malloc_alloc_oom_handler = f;
 return(old);
 }
};
// malloc申请空间失败时代用该函数
template <int inst>
void * __malloc_alloc_template<inst>::oom_malloc(size_t n)
{
void (* my_malloc_handler)();
void *result;
for (;;) 
{
   // 检测用户是否设置空间不足应对措施,如果没有设置,抛异常,模式new的方式
   my_malloc_handler = __malloc_alloc_oom_handler;
   if (0 == my_malloc_handler)
   {
       __THROW_BAD_ALLOC; 
   }
   
   // 如果设置,执行用户提供的空间不足应对措施
   (*my_malloc_handler)();
   
   // 继续申请空间,可能就会申请成功
   result = malloc(n);
   if (result)
       return(result);
}
}
typedef __malloc_alloc_template<0> malloc_alloc;

相关推荐

  1. STL-空间配置

    2024-04-27 00:20:01       54 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-27 00:20:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-27 00:20:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-27 00:20:01       82 阅读
  4. Python语言-面向对象

    2024-04-27 00:20:01       91 阅读

热门阅读

  1. 交换机的八大功能

    2024-04-27 00:20:01       32 阅读
  2. 授人以渔 选购篇十二:路由器选购要点

    2024-04-27 00:20:01       34 阅读
  3. 4 -26

    4 -26

    2024-04-27 00:20:01      29 阅读
  4. 部署一个自己的GPT客户端[以ChatGPT-Next-Web为例]

    2024-04-27 00:20:01       36 阅读
  5. NumPy 1.26 中文官方指南(四)

    2024-04-27 00:20:01       27 阅读
  6. MySQL查出时间比实际晚8小时的解决方案

    2024-04-27 00:20:01       26 阅读
  7. Android ViewModel使用模板

    2024-04-27 00:20:01       35 阅读
  8. 【小浩算法cpp题解】合并两个有序链表(21)

    2024-04-27 00:20:01       34 阅读
  9. nvm 错误

    2024-04-27 00:20:01       30 阅读
  10. 展开说说:Android动画使用

    2024-04-27 00:20:01       27 阅读
  11. 什么是裸金属服务器?

    2024-04-27 00:20:01       36 阅读
  12. 原型模式(上机考试抽题)

    2024-04-27 00:20:01       31 阅读
  13. 01_numpy

    2024-04-27 00:20:01       36 阅读