C语言 — 一个简单内存池模型的实现
内存池原理说明
我们有时候在做一个项目时,为了避免引起内存泄漏等常见的问题。往往会自己实现一个内存池,并定义相应的函数对其进行管理。当想用某一块内存时,就调用相应的接口进行分配,不用时再调用相应的接口将其释放掉。当发现访问内存访问越界时可以及时返回错误值,同时也不会因为内存泄露的原因无限制使用内存导致系统宕机。当我们的内存池模型具备以上功能的时候,我们也就完了成一个内存池基本的模型。
下面是我们模拟C语言内存分配函数malloc()和free(),我们这里也定义两个函数alloc和afree,进而模拟C语言内存的分配的实现。实现一个最简单的内存池模型,当然了,我们可以使用这个最简单的模型来理解操作系统的内存管理机制和内存池的原理。
建议内存池的基本原理如下:
- 定义一个大的字符数组,模拟一块内存池。
- 让alloc对一个大的字符数组allocbuf中的空间进行分配,该数组是alloc和afree两个函数私有的数组。
- 由于alloc和afree处理的对象是指针而不是数组下标,因此,其他函数无需知道该数组的名字,这样可以在alloc和afree处理的对象是指针而不是数组下标,因此,其他函数无需知道该数组的名字。
- 他可以在调用malloc函数或量操作系统申请一个指向操作系统申请一个指向无名存储块的指针获得。
- allocbuf中的空间使用情况也是我们需要了解,因此用allocp指针指向allocbuf数组中下一个空闲单元。当调用alloc申请n个字符时空间时,alloc检查allocbuf中的下一个空闲单元。当调用alloc申请n个字符的空间时,alloc检查allocbuf中有没由足够的空闲空间。如果有足够的空闲空间,则返回空闲块的当前位置,如果空间不够则返回0.
下面是简易内存池的实现原理图:
其实这个模型可以帮助我们理解关于malloc和free函数的很多东西。
代码实现
- 这里只简单的实现了内存的分配和释放,对于这个模型,我们其实还可以实现更多的东西,比如查看内存剩余空间,对这个内存空间再分成不同的块等等。
#define ALLOCSIZE 10000 /* 可用空间的大小,这里我们设置内存池的空间大小为10000字节 */
static char allocbuf[ALLOCSIZE]; /* alloc使用的存储区 */
static char *allocp = allocbuf; /* 下一个空闲位置 */
char *alloc(int n)
{
if(allocbuf + ALLOCSIZE - allocp > n) { /* 有足够的空间 */
allocp += n;
return allocp - n; /* 分配前的指针P */
} else { /* 空间不够 */
return 0;
}
}
void afree(char *p) /* 释放p指向的存储区 */
{
if(p >= allocbuf && p < allocbuf + ALLOCSIZE )
allocp = p;
}