汇编网首页登录博客注册
answerooo的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  

[2009-02-06 15:54] 第一课 函数malloc的实现_malloc.c

//malloc.c 

#define NULL 0  

union Node{  
      
    struct{  
        union Node *next;  
        unsigned int size;  
    }s; 

    long a;      /*内存对齐*/ 
};  

typedef union Node Header;  

static Header *startup = NULL;   /*空闲链表开始指针*/ 

extern unsigned int _heapstart;  

const int E = 5;  

void *malloc(unsigned int nunits)  

    Header *p, *prevp; 
    Header *morecore(unsigned int); 
      
    if((prevp = startup) == NULL) 
    { 
        startup = (Header *)(_heapstart - 16); 
        startup->s.size = 0; 
        startup->s.next = startup; 
    }  

    nunits = (nunits + 3) & ~3;    /*内存对齐*/ 

    for(p = startup->s.next; ; prevp = p, p = p->s.next) 
    { 
        if(p->s.size >= nunits) 
        { 
            if(p->s.size <= nunits + E) 
            { 
                prevp->s.next = p->s.next; 
            } 
            else 
            { 
                p->s.size -= (nunits + sizeof(Header)); 
                (char *)p += (p->s.size + sizeof(Header)); 
                p->s.size = nunits; 
            } 

            startup = prevp; 
            return (void *)(p + 1); 
        } 

        if(p == startup) 
        { 
            if((p = morecore(nunits)) == NULL) 
            { 
                return NULL; 
            } 
        } 
    }      
}  

Header *morecore(unsigned int num)  
{  
    Header *up;  
    unsigned int temp;  
    unsigned int former;      
    void free(void *); 

    former = _heapstart;  
    temp = _heapstart + sizeof(Header) + num;  
      
    if(temp < 65535) 
    {  
        _heapstart = temp; 
        up = (Header *)former; 
        up->s.size = num; 
        free((void *)(up + 1)); 
        return startup; 
    } 
    else 
    { 
        return NULL; 
    } 


void free(void *ptr) 

    Header *p; 

    Header *freep = (Header *)ptr; 

    for(p = startup; ;p = p->s.next) 
    { 
        if((freep - 1) > p && (freep - 1) < p->s.next)  /*在两个空闲块之间*/ 
        { 
            break; 
        } 
        if(p >= p->s.next && ((freep - 1) > p))         /*在空闲链表的末尾*/ 
        { 
            break; 
        } 
    } 
             
        if(((char *)(freep - 1) + (freep - 1)->s.size + sizeof(Header)) == p->s.next) 
        { 
        (freep - 1)->s.size += p->s.next->s.size + sizeof(Header); 
        (freep - 1)->s.next = p->s.next->s.next; 
        } 
        else 
        { 
                (freep - 1)->s.next = p->s.next; 
        } 

         
    if(((char *)p + p->s.size + sizeof(Header)) ==  (freep - 1)) 
    { 
        p->s.size += (freep - 1)->s.size + sizeof(Header); 
        p->s.next = (freep - 1)->s.next; 
    } 
    else 
       { 
               p->s.next = (freep - 1);     
        } 
         
        startup = p; 
}
评论次数(5)  |  浏览次数(1144)  |  类型(默认类型) |  收藏此文  | 

[  mywiil   发表于  2009-02-10 14:38  ]

谢谢老哥对我的提醒。

[  mywiil   发表于  2009-02-10 14:40  ]

回头我在修改一下。

[  游客   发表于  2009-02-10 16:49  ]

我觉得博主的free函数中有问题。
for(p = startup; ;p = p->s.next)  
    {  
        if((freep - 1) > p && (freep - 1) < p->s.next)  /*在两个空闲块之间*/  
        {  
            break;  
        }  
        if(p >= p->s.next && ((freep - 1) > p))         /*在空闲链表的末尾*/  
        {  
            break;  
        }  
    }  
这段代码的逻辑不严谨吧。如果startup不是地址最小的情况下,如果符合freep的放于中间的位置在startup左边,程序从startup向右开始遍历,等到了末尾,就符合末尾插入的条件了,而不能继续遍历到sratrup。也就是说,符合尾部插入的条件使得整个循环链表没有遍历完全。

[  answerooo   发表于  2009-02-10 17:05  ]

回复楼上:
-------------------------------------------
如果startup不是地址最小的情况下,如果符合freep的放于中间的位置在startup左边,程序从startup向右开始遍历,等到了末尾,就符合末尾插入的条件了,
-------------------------------------------
要看明白我的程序,你说的那种情况是不会“等到了末尾,就符合末尾插入的条件了”

[  mywiil   发表于  2009-02-10 17:46  ]

是这样,因为&&后面的限制条件能够起作用。
我写的就罗索了,我用了两个循环,第一个循环判断是否是在某两个结点之间;再一个循环用来找到末尾。这样,其实那个(freep-1)>p在我那种情况下就没用了,所以我给去掉了。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码