原文:https://arjunsreedharan.org/post/148675821737/memory-allocators-101-write-a-simple-memory
与本文相关的代码: github.com/arjun024/memalloc
可以访问译者的github ,阅读体验更佳...
本文的话题是用C语言实现一个简单的内存分配器。这里我们将实现 malloc(), calloc(), realloc() and free() 。
这是一个入门水平的文章,不会涉及到每个细节。这个内存分配器不会追求速度和效率,也没有考虑内存分配的内存页对齐问题,我们的目标就是实现一个可以工作的内存分配器,仅此而已。
如果你想要查看完整的代码,可以访问github repo memalloc
在开始实现之前,我们需要先熟悉一个程序的内存布局。每个程序都运行在各自的虚拟地址空间中,这个虚拟地址空间包含5个部分:
Text section: 该部分包含供处理器执行的二进制指令序列 Data section: 包含已初始化的静态数据(non-zero initialized static data) BSS (Block Started by Symbol,以符号开头的块) : 包含未未初始化的数据. 未初始化的数据将会被初始化为0并被放在这个区域. Heap: 包含动态分配的数据. Stack: 包含自动分配的变量,函数参数,基指针拷贝等。
如图所示,stack 和 heap 的增长方向是相反的。有时候,我们将 data, BSS 和 heap 三个部分 统称为 "data segment",data segment的结尾由一个指针确定,叫做 program break, 简称 brk ,brk 指向 heap 的末尾处。
现在,我们要在 heap 上 分配更多的空间,我们需要请求系统往内存增长方向移动 brk,同理,释放内存的时候,需要请求系统往内存减小的方向方向移动brk。
如果我们的系统环境是Linux或者其他的类Unix系统, 我们可以使用系统调用 sbrk()
来操纵 program break 。
调用 sbrk(0)
获取 program break 的当前地址 . 调用 sbrk(x)
,x 为正数时,请求分配 x bytes 的内存空间 . 调用 sbrk(x)
, x 为负数时,请求释放 x bytes 的内存空间 . 失败时,sbrk()
返回 (void*) -1
.
老实说,sbrk()
并不是我们现在的最佳选择,更好的选择是 mmap()