现在,一般来说,我们可以实现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翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

(转)简单的Malloc实现的更多相关文章

  1. 简单了解malloc分配内存

    直接看代码 #include <stdio.h> #include <malloc.h> int main() { * * ); printf("分配后请查看内存&q ...

  2. 转:如何实现一个malloc

    如何实现一个malloc 转载后排版效果很差,看原文!   任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉. ...

  3. 如何实现一个malloc

    任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...

  4. 【转】如何实现一个malloc

    任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...

  5. 如何实现一个malloc(转)

    本文转自博文如何实现一个malloc.就如作者本人所说,该博文大量参考了A malloc Tutorial,所以对照着阅读这两篇文章更能加深理解. 任何一个用过或学过C的人对malloc都不会陌生.大 ...

  6. [转]如何实现一个malloc

    任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...

  7. 浅谈malloc()和free()工作原理

    编程之路刚刚开始,错误难免,希望大家能够指出.  malloc()和free()是我经常需要用到的函数,一般情况下,C程序使用malloc()在堆上分配内存,free()释放内存,两者的参数和返回值就 ...

  8. malloc基本实现

    转自:http://www.cnblogs.com/wangshide/p/3932539.html 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间 ...

  9. [转] malloc基本实现

    任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...

随机推荐

  1. 物联网典型场景之智能家电,使用JOSH技术带来的优势和机会~

    很多人一直问,用JOSH技术如何改变智能家电,有没有真正的必要? 一部分人的观点:我可以用嵌入式C.汇编完成家电的程序,毕竟这些设备的程序很简单: 另一部分的人:智能家电互相的连接都一直有人在做啊,并 ...

  2. openresty nginx systemtap netdata

    https://openresty.org/cn/getting-started.html https://github.com/openresty https://github.com/openre ...

  3. Can't locate Math/Round.pm in @INC

    遭遇报错: Can't locate Math/Round.pm in @INC 经过亲自测试,下面的命令解决了我的问题. yum install perl-Math-Round 参考资料 ===== ...

  4. GET请求的请求参数最大长度

    在HTTP规范RFC-2616中有这样一段描述: The HTTP protocol does not place any a priori limit on the length of a URI. ...

  5. jquery动画控制非css属性

    JQuery的animate()方法可以通过渐变的更改CSS属性来实现简单的动画效果, 比如 $("#box").animate({height:"300px" ...

  6. table中td文字超出长度用省略号隐藏超出内容,鼠标点击内容全部显示

    1,设置css样式 <style>table {width: 100%;float: left;table-layout:fixed;width:600px;border:1px soli ...

  7. python 进程和线程-进程和线程的比较以及分布式进程

    进程和线程的比较 参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/1017631469467456 我们介绍了多进程和多线程,这是实现多任 ...

  8. PyCharm使用分享

    常用快捷键 PyCharm的快捷键可以通过Setting->keymap查看和设置,如果不知道具体在哪个位置,可以在搜索框中搜索 如果不习惯PyCharm默认的快捷键,也不想去设置,比如习惯了使 ...

  9. Jquery实现左右轮播效果

    首先展示下静态布局h5代码,代码非常简单. <div id="slide"> <ul class="pic-list"> <li& ...

  10. 用JSON.stringify去实现深拷贝的弊端

    无法处理function啦还有RegExp啦,还有无法处理循环引用对象(这个我还没有test) 就前两点的话 var a={ a:, b:new RegExp('test'), c:function( ...