(转)简单的Malloc实现

现在,一般来说,我们可以实现malloc使得对malloc的调用将会被映射到系统调用sbrk上,sbrk(n)将会移动程序中断的位置-也就是程序的data段的最后。-偏移n个字节,这意味着,n个字节的内存就被分配给了当前程序

我们最终的实现大概看起来会像这样

void* malloc (unsigned n) 
{
    return sbrk(n);
}

然而,调用一次sbrk是非常昂贵的。因此,如果我们的malloc实现,通过一次sbrk调用分配到了一块很大的内存块,当需要的时候再把这块内存分成更小的部分,相比不论什么时候需要分配了就去调用malloc,将会更加高效一些。

记住,当申请到的内存已经用完的时候,malloc将不得不调用一次sbrk,此时,新申请到的大块内存将和原来的大块内存不是连续的。

另外,我们将会想要重新使用那些我们已经释放的内存,因此我们的malloc实现应该保持记录当前对程序可用的内存。由于一段时间后,这些可用的小的内存块将不再连续,我们将会使用一个链表保持记录这些可用的内存块。

 

最后,我们需要记录在我们的链表中,每一小块可用的内存有多大,我们给我们的链表结构添加一个size域

把上面所有的结合起来,最终,这就是一个简单的malloc的实现。

#define MINIMUM 1024  /*通过sbrk分配的最小内存 */

struct header {
    struct header* next; /* 指向下一个节点的指针 */
    unsigned size;
}

static header base; /* 链表头 */
static header* freep = NULL; /* 空闲内存的链表 */

void* malloc (unsigned n) 
{
    header* p, *prev;
    unsigned nunits;
    
    nunits = (n + sizeof(header) - 1) / sizeof(header);
    /* 检查是否还有有空闲内存的链表 */
    if ((prev = freep) == NULL) {
        base.next = freep = prev = &base;
        base.size = 0;
    }
    
    for (p = prev->next; ; prev = p, p = p->next) {
        /* 空间的内存是否足够? */
        if (p.size >= nunits) { 
            if (p->size == nunits) /* 如果够? */
                prev->next = p->next;
            else { /* 不够就分配不够的部分 */
                p->size -= nunits;
                p += p->size;
                p->size = nunits;
            }
            freep = prev;
            return (void *)(p + 1);
        }
        
        if (p == freep) /* wrapped around list */
            if ((p = moremem(nunits)) == NULL)
                return NULL; /* 没有空内存 */
    }
}

/* 从内核中请求更多的内存 */
header* moremem (unsigned n) 
{
    char* p;
    header* up;
    
    if (n < MINIMUM)
        n = MINIMUM;
        
    p = sbrk(n * sizeof(header));
    
    if (p == (char *) -1) /* 没有空闲内存 */
        return NULL;
        
    up = (header *) p;
    up->size = n;
    free((void *)(up + 1));
    
    return freep;
}

这就是这个函数的要点了,我就不麻烦的实现free(n)了,但是free函数所做的仅仅是把n字节大小的空间插入到链表freep适当的地方就可以了

著作权声明:本文由http://www.cnblogs.com/lazycoding翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

posted @ 2018-09-29 16:49  cs_wu  阅读(647)  评论(0编辑  收藏  举报