zoukankan      html  css  js  c++  java
  • C语言中malloc函数实现 CHRIS

    该实现使用大容量的静态数组作为堆,但也可使用操作系统调用分配堆。定义了一个数据类型Header保存每个存储器块的簿记信息,定义了具有Header类型元素的堆数组,这样就可以很容易地将簿记信息保存在存储器块中。类型Header包含了3块信息:指向列表的下一个块的指针,当前分配空间的长度,后面的自由空间的长度。另外,类型Header的定义还使用了一个union声明和Align数据类型,这是将存储器元素排在合理的字节边界上,根据系统的不同,这有时是需要的,有时是不需要的。

      在malloc函数中,当申请空间时,至少要分配两个Header元素节点,有什么原因吗?当然有,因为每个空间块都包含两部分:空间头和空间体。空间头是为维护堆而设计的,说到底就是维护已用空间链表,为搜索空闲空间和释放已用空间服务。空间体是供用户读写的,当malloc函数返回给用户一个指针时,用户就可以设定自己的规格,比如强制转换成int或double类型,接下来就可以按照这种规格进行读写了。需要注意一点,空间头是不能被用户访问的,它是用来维护堆的,不是为用户服务的,所以malloc函数返回的指针是指向空间体的,而不是指向空间头的,理所当然free函数得到的指针也是指向空间体的。可是为了释放空间,free函数需要得到该空间的空间头信息,所以实现时需要把指针调整一下,改为指向空间头,此情形下,加一即可。另外一点,空间头和空间体同为Header类型,用union声明再合适不过。下面就是malloc函数和free函数的实现代码:

    #define NULL 0
    #define MEMSEZE 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* malloc(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->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 free(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->next);
         if(p!=bp) return;
         prev->s.freesize+=p->s.usedsize+p->s.freesize;
         prev->s.next=p->s.next;
         memptr=prev;
    }

  • 相关阅读:
    Selenium IDE的使用
    add jars、add external jars、add library、add class folder的区别
    java中equals和==区别
    java分布式事务
    六边形架构模式
    JAVA分布式事务原理及应用(转)
    HashMap的实现原理和底层数据结构
    HashMap实现原理分析
    深入Java集合学习系列:HashMap的实现原理
    23种设计模式汇总整理
  • 原文地址:https://www.cnblogs.com/chriszsy/p/13216140.html
Copyright © 2011-2022 走看看