分享

C语言中malloc函数实现

 孤步 2012-07-31

C语言中malloc函数实现

  该实现使用大容量的静态数组作为堆,但也可使用操作系统调用分配堆。

定义了一个数据类型Header保存每个存储器块的簿记信息,定义了具有Header类型元素的堆数组,

这样就可以很容易地将簿记信息保存在存储器块中。

 

  类型Header包含了3块信息:指向列表的下一个块的指针,当前分配空间的长度,后面的自由空间的长度。

 

       另外,类型Header的定义还使用了一个union声明和Align数据类型,这是将存储器元素排在合理的字节边界上,

       根据系统的不同,这有时是需要的,有时是不需要的。

 

//malloc函数中,当申请空间时,至少要分配两个Header元素节点,有什么原因吗?

当然有,因为每个空间块都包含两部分:空间头和空间体。

 

  空间头是为维护堆而设计的,说到底就是维护已用空间链表,为搜索空闲空间和释放已用空间服务。

 

       空间体是供用户读写的,当malloc函数返回给用户一个指针时,用户就可以设定自己的规格,

       比如强制转换成intdouble类型,接下来就可以按照这种规格进行读写了。

 

       需要注意一点,空间头是不能被用户访问的,它是用来维护堆的,不是为用户服务的,所以malloc函数返回的指针是指向空间体的,

 

       而不是指向空间头的,理所当然free函数得到的指针也是指向空间体的。

 

       可是为了释放空间,free函数需要得到该空间的空间头信息,所以实现时需要把指针调整一下,改为指向空间头,

       此情形下,加一即可。另外一点,空间头和空间体同为Header类型,用union声明再合适不过。

 

       下面就是malloc函数和free函数的实现代码:

*/

#include "stdio.h"

#include <iostream>

using namespace std;

 

#define NULL 0

#define MEMSIZE 8096

 

typedef double Align;

typedef union header

{

       struct

       {

              union header* next;

              unsigned usedsize;

              unsigned freesize;

       }s;

       Align a;

} Header;

static Header mem[MEMSIZE];

static Header* memptr=NULL;

 

void* mymalloc(unsigned nbytes)

{

       Header *p,*newp;

       unsigned nunits;

       nunits=(nbytes+sizeof(Header)-1)/sizeof(Header)+1;

      

       if(memptr==NULL)

       {

              memptr->s.next=memptr=mem;

              memptr->s.usedsize=1;

              memptr->s.freesize=MEMSIZE-1;

       }

 

       for(p=memptr;(p->s.next!=memptr) && (p->s.freesize<nunits);p=p->s.next);

       if(p->s.freesize < nunits) return NULL;

      

       newp=p+p->s.usedsize;

       newp->s.usedsize=nunits;

       newp->s.freesize=p->s.freesize-nunits;

       newp->s.next=p->s.next;

       p->s.freesize=0;

       p->s.next=newp;

       memptr=newp;

      

       return (void*)(newp+1);

}

void myfree(void* ap)

{

       Header *bp,*p,*prev;

       bp=(Header*)ap-1;

      

       for(prev=memptr,p=memptr->s.next;

       (p!=bp) && (p!=memptr);prev=p,p=p->s.next);

      

       if(p!=bp) return;

      

       prev->s.freesize+=p->s.usedsize+p->s.freesize;

       prev->s.next=p->s.next;

       memptr=prev;

}

 

void main()

{

       /*测试*/

    int i;

    int *arry=(int *)mymalloc(100*sizeof(int));

    for(i=0;i<100;i++)

              arry[i]=i+1;

    for(i=0;i<100;i++)

              printf("%d ",*arry++);

    getchar();

}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多