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

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

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

typedef struct HeadStruct{

     size_t size;

     void *buf;

     struct HeadStruct *pre,*next;

     int used;

}

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

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

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

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

程序实现如下:

#include 
#include 
#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;
}



你可能感兴趣的:(模拟实现c语言中的动态内存分配malloc函数)