【C++内存管理机制】学习笔记(5):pre-class allocator1/2、static allocator、macro for static allo

150 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情

前言

在之前我们知道,使用malloc分配内存空间时,会得到一个cookie,而其又有很多我们暂时不需要的填充

当我们需要new很多对象时(多次调用malloc),那么就会造成很多的内存浪费

这时候就需要我们自己进行内存管理(自己开内存,使用内存,也就是需要利用重载实现)

内存管理的目标:

  • 速度(要快)
  • 减少malloc的调用次数(减少不必要内存空间的浪费)

pre-class allocator1

首先我们对operator new/delete进行重载

第一次开内存时,我们就开一个足够大的内存,同时进行内存切块,方便后面使用(这样下一个对象需要内存时,暂时就不需要malloc去分配,直接使用我们已经分配好的内存就好了,这样就可以减少cookie不必要的空间)

在这里插入图片描述

这里引入了一个概念:内存池,先创建出一大段连续空间的内存,然后将其切割成一小段一小段。

将创建的元素对象放在内存池切分好的各分段小内存片中,这样避免了多次调用new而造成生成多个带有cookie的内存空间。通过内存池的观念,可以生成一大段只带有两个头尾cookie的内存空间,而该一大段内存空间又被切分成每一小段的内存空间,且其中的每一小段内存空间片都可以共享这一整体的cookie信息。

那么怎么切分内存且记录下来? 答:我们使用一个链表进行记录。保存头指针,指向内存是下一块内存的地址,依次类推。

测试程序结果:

在这里插入图片描述 上图说明我们新new的对象在内存中是连续的,没有多余的内存开销

这里得看系统此时为我们分配的内存空间是否是连续的

这样做虽然减少了cookie的浪费,但是也引入了链表这一开销。

pre-class allocator2

对pre-class allocator1进行改进

在这里插入图片描述 pre-class allocator1适应用了一个指针,浪费空间

这个版本通过union关键字来减少使用next而所占耗的内存(没有懂,为啥减少了?)

疑问解答:www.bbsmax.com/A/kvJ3086Q5…

static allocator

改进后依然存在一个问题:每次都需要在类中进行实现,重复工作太多

那么就:定义一个allocator类,用于完成opertator new/detlete操作

在这里插入图片描述

看看是如何使用的: 在这里插入图片描述 从上图可以看出,这样使用就方便多了...(先声明,再调用即可)

macro for static allocator

后面又发现,每次都要写myalloc,代码还是有重复性

那么就引入宏!

在这里插入图片描述

每次需要使用时,写上对应的宏即可

global allocator

STL为了适配不同的容器分配器,又进行了改进,如下(暂先了解)

在这里插入图片描述

总结

越学越难 ,得多看几遍

每看一遍都有新的领悟