内存管理的一个实验

之所以会写这个程序是因为培训中有一课是 TDD test-driven devp , 先写测试后写程序,是一种比较神奇的编程方法,看似不可能,其实这样程序出错的可能性更小。如果大家对 TDD 有兴趣可以去看看其他的书,我就不讨论了。接下来要谈的 MemPool 是课中实践题目,但是由于系统是 linux ,搞的我晕头转向的(命令行操作路径切换),程序没怎么写, linux 的操作到时学会了一些,呵呵。

MemPool 是自己实现的一个内存管理的方法,主要的想法就是每次用户申请内存我们先分配给他,然后当用户释放时我们不调用 free ,而是把申请的内容保持起来,下次再申请直接把这个空间给用户。题目要求分配内存的大小必须是 8byte 对齐( 8 16 32… ),然后维护一个表格,实现 MemPool_Alloc uint size )和 MemPool_Free void*p )两个方法

Size

Total

Free

Point

8

1

0

NIL

16

1

1

XXXXXX

32

0

0

NIL

Total 是已经申请的内存块数, Free 是当前空闲的快数, Point 指向一个空闲内存的单项链表, NIL 表示空。

题目咋看起来比较简单,只要每次用户调用 MemPool_Alloc 时检查下是否有空闲块,有就返回单链表的第一个元素,没有就申请一块内存;当调用 MemPool_Free 时,把这块内存链到单链表中就 ok 了。这里为了简单起见,把表格定死,假设只有 8 16 32 ,这 3 个大小,不定死的话就是把这个表格变为一个单项链表。

先说我自己最初的想法:定义 2 个结构体,一个表示表格的每一行,另一个表示每个内存块。刚开始写的很顺,后来写到 MemPool_Free 时问题就出来了。因为只传进来一个参数 void *p ,而我们要归还的话必须得知道这块内存的大小,那怎么知道那?这得取决于我们 MemPool_Alloc 是怎么实现的了,最后我实现的方法是每次新申请内存后就把这块内存链起来,再增加一个 bool bIsFree 选项。这样每次归还时我只要查找到这个 void*p 属于哪个 Memory, 然后就找到了属于哪个 Block ,再设置 bIsFree true ok 了。分配时查找哪个 Memory bIsFree true ,否则申请一个。虽然这样是可以的,但是总要全部查找一遍总觉得效率不高。后来我去问了公司里的一个同事,他是培训中写完程序。发现他的方法很好。

typedef struct tagMemory

{

bool bIsFree;

void *pMem;// 这个是要我们返回给用户

struct tagMemory *pNext;

}Memory;

typedef struct tagBlock

{

//block size

int nTotal;

int nFree;

Memory *pFreeHead;

}Block;

同事的方法:先把结构体改一下, Memory bool bIsFree 去掉就可以了。因为我唯一遇到的问题就是不知道归还的内存的大小,那我们想办法知道就可以了。或许你也会想到调用系统 free 时不是也没指定它的大小么,是的,因为系统分配时纪录了该块内存的大小。现在我们的方法也是一样的,就是申请空间时多申请一个 int 类型大小的空间来保存空间的大小(其实也可以是其他类型够大就可以了), Alloc 时的关键代码如下:

Size

Mem

Void *p = malloc(sizeof int + size);

int *pInt = (int*)p;

*pInt = size;

p = (void*)(pInt+1);

return p;

这里有些对 void* 指针操作的注意事项,

1. 不能直接对 void* 类型的指针进行解引用(就是取里面的内容),因为编译器不知道 void* 指针指向类型的大小。

2. 不能对 void* 指针用 sizeof

3. void* 指针和其他类型的指针可以互相转换(也不是绝对)

最终 Free 时的关键代码如下:

Free((void*)((int*)p-1));

其实这个类似 MemPool 的东西在《 c 语言接口与编程》里也有,只不过他是通过 hash 来查找的,大家有兴趣可以去看看。这段时间以后一直都在学习语言或者是没有接触过的技术,对于这种需要技巧(对我而言)的东西很久没写了,感觉不错,趁热就把它纪录下来。

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...