其实说的就是C语言的malloc和free的实现机制,实现算法。在阅读了内存管理内幕(以下文字基于这个链接)这篇文章的前半部分后,深有感觉,这全是重要的思想啊。
关键词:内存控制块MCB
MCB这东西是一个结构体,具体定义如下
struct mem_control_block { int is_available;//这个字段值为0的时候表示还没有被其他程序使用 int size;//这个字段表示这个MCB示例所管理的内存长度 };除此之外,需要三个全局变量来控制分配程序的进行
int has_initialized = 0; //决定分配程序是否已经初始化 void *managed_memory_start;//保存系统返回的系统在用户任何malloc都没调用前的当前系统终端点 void *last_valid_address;//同上,不过这个值会在每次malloc()之后得到更新,指向最新的地址
好了,有了这个基本的概念,开始分析吧,会慢慢了解到以上变量的作用。
c的分配heap程序在开始运作之前,需要初始化,就需要调用
void malloc_init() { last_valid_address = sbrk(0); //你看,先返回系统的当前终端点 managed_memory_start = last_valid_address; //保存一下 has_initialized = 1; //表示已经初始化过了 }这个函数就不再被调用了。
开始首次调用malloc()
last_valid_address | managed_memory_start | ----------------------------------------->首先,可以理解这两个值指向同一个地址
在此之后,把用户请求的内存长度加上管理这快内存的MCB长度
memory_location = 0; current_location = managed_memory_start; while(current_location != last_valid_address)执行到此处时,由于是第一次使用malloc,所以发现while条件不成立,离开了
if(! memory_location) { sbrk(numbytes);//把中断点移动numbytes个字节 memory_location = last_valid_address;//把这个变量的值给要返回给用户使用的变量 last_valid_address = last_valid_address + numbytes;//更新这个指针变量,为下一个malloc做准备 current_location_mcb = memory_location;//把MCB放到此处 current_location_mcb->is_available = 0;//设置0,说明这块内存已经被使用了,以后对这块内存的返回都是不允许的 current_location_mcb->size = numbytes;//设置MCB要管理的字节数 }
managed_memory_start last_valid_address | | -------------------------------------------------------> |<--1-->|<----------------2--------------------|> | current_location_mcb 1:内存控制块长度 2:用户请求的内存长度1 + 2 = numbytes
最后来一句
memory_location = memory_location + sizeof(struct mem_control_block);并返回这个变量,所以,我们用户使用的内存控制块后面的那段内存,MCB对我们是透明的。malloc目的达成.
对于free的话
void free(void *firstbyte) { struct mem_control_block *mcb; mcb = firstbyte - sizeof(struct mem_control_block); //把地址回退到MCB的位置 mcb->is_available = 1; //再把MCB的管理标记设为1,说明目前没有程序使用此块内存 return; }
那么对于第二次malloc的话,很明显
while(current_location != last_valid_address)将成立
进入循环体后,先得到current_location这个地址开始出的MCB,通过强制转换
current_location_mcb = (struct mem_control_block *)current_location;得到。
下面的就是判断可不可用啦,长度够不够我要的啦,其中只要有一个不满足,就要找下一个MCB。
一环套一环的能找下去的根本条件就是本次得到的MCB里面的size字段,不断照着它偏移就可以了。
如果可用且长度够,那么就把current_location + MCB长度偏移后的地址返回给用户使用。
如果执行一次就跳出了呢,那么就照着第一次malloc的方式再分配内存。
如此如此.
总结一下:这个分配算法有点像我目前做的网络通讯协议,数据包括报头和数据段。报头定义了一系列有关数据的属性。看来都有通性。
managed_memory_start一直指向第一个地址(暂且这么说),它是一环套一环查找的基础
last_valid_address只要使用了malloc,就得到更新。
现在想想,怎么这么像队列呢,一个head指针永远指向头,一个tail指针永远指向尾。
谢谢观赏。
作者:ma52103231 发表于2013-1-25 17:26:37 原文链接
阅读:7 评论:0 查看评论