模拟实现c语言中的动态内存分配malloc函数

来源:互联网 发布:寰宇人生软件下载 编辑:程序博客网 时间:2024/05/24 15:37

动态存储器分配器维护着一个进程的虚拟的存储器区域,称为堆(heap)。分配器将堆视为一组不同大小的块的集合来维护。每个块就是一个连续的虚拟存储器片(chunk),要么是已经分配的,要么是空闲的。

我们这里把内存堆空间模拟为一个字节数组buf[1000],块的数据结构为:

typedef struct HeadStruct{

     size_t size;

     void *buf;

     struct HeadStruct *pre,*next;

     int used;

}

堆的组织方式为双向链表。要实现malloc函数,就必须考虑几个问题:
1 空闲块的组织:我们如何记录空闲块

2 放置:我们如何选择一个合适的空闲块来放置一个新分配的块

3 分割:在我们将一个新分配的块放置在某一个空闲块之后,如何处理这个空闲块的剩余部分

4 合并:我们如何处理一个刚刚被释放的块

程序实现如下:

#include <stdio.h>#include <stdlib.h>#define HeadSize (sizeof(HeadStruct))char buf[1000];//模拟内存堆typedef struct HeadStruct{  size_t size;//块的大小  void *buf;//有效的载荷  struct HeadStruct *pre,*next;//前驱和后继,用双向链表实现堆  int used;//表明此块空闲与否}HeadStruct;//堆中块的结构体void Init_heap(){  HeadStruct *p=(HeadStruct *)buf;  p->size=sizeof(buf)-HeadSize;  p->buf=(char *)p + HeadSize;//p should be cast to char*  p->pre=p->next=NULL;  p->used=0;}void list_blocks(){  HeadStruct *p=(HeadStruct *)buf;  while(p)  {    printf("addr:%d,size:%d,used:%d\n",(char *)(p->buf)-buf,p->size,p->used);    p=p->next;  }}void *myalloc(size_t size){  HeadStruct *p=(HeadStruct *)buf;  while(!((p!=NULL)&&(p->size-size>HeadSize)&&(p->used==0)))  {    p=p->next;  }  if(p==NULL)  {    printf("ERROR!");    return NULL;  }  else  {    HeadStruct *rest=(HeadStruct *)((char *)(p->buf)+size);    rest->buf=(char *)rest+HeadSize;    rest->size=p->size-size-HeadSize;    rest->next=p->next;    if(p->next)      p->next->pre=rest;    p->next=rest;    rest->pre=p;    rest->used=0;    p->size=size;  }  p->used=1;  return p->buf;}void myFree(void *mem){  HeadStruct *actual=(HeadStruct *)((char *)mem-HeadSize);  //堆增长的方式是向高地址增长,要找到块的首地址就的减去块头的大小  if(!mem || 0==actual->used)  {    printf("FREE ERROR!");    return;  }  actual->used=0;  HeadStruct *tmp;  if(actual->next && actual->next->used==0)  {//合并    actual->size+=actual->next->size+HeadSize;    tmp=actual->next->next;    actual->next=tmp;    if(tmp)      tmp->pre=actual;  }  if(actual->pre && actual->pre->used==0)  {    actual->pre->size+=actual->size+HeadSize;    actual->pre->next=actual->next;    if(actual->next)      actual->next->pre=actual->pre;  }  return;}int main(){  Init_heap();  list_blocks();  int *a=(int *)myalloc(sizeof(int)*100);  list_blocks();  char *b=(char *)myalloc(sizeof(char)*100);  list_blocks();  myFree(a);  myFree(b);  list_blocks();  return 0;}



原创粉丝点击