(转)简单的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翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!
(转)简单的Malloc实现的更多相关文章
- 简单了解malloc分配内存
直接看代码 #include <stdio.h> #include <malloc.h> int main() { * * ); printf("分配后请查看内存&q ...
- 转:如何实现一个malloc
如何实现一个malloc 转载后排版效果很差,看原文! 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉. ...
- 如何实现一个malloc
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...
- 【转】如何实现一个malloc
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...
- 如何实现一个malloc(转)
本文转自博文如何实现一个malloc.就如作者本人所说,该博文大量参考了A malloc Tutorial,所以对照着阅读这两篇文章更能加深理解. 任何一个用过或学过C的人对malloc都不会陌生.大 ...
- [转]如何实现一个malloc
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...
- 浅谈malloc()和free()工作原理
编程之路刚刚开始,错误难免,希望大家能够指出. malloc()和free()是我经常需要用到的函数,一般情况下,C程序使用malloc()在堆上分配内存,free()释放内存,两者的参数和返回值就 ...
- malloc基本实现
转自:http://www.cnblogs.com/wangshide/p/3932539.html 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间 ...
- [转] malloc基本实现
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...
随机推荐
- git账户配置
一.生成github的ssh key ssh-keygen ssh-keygen -t rsa -f ~/.ssh/zzf073_rsa -C zzf073@163.com 二.配置账户公钥 1.查看 ...
- 优化、分析Mysql表读写、索引等操作的sql语句效率优化问题
为什么要优化: 随着实际项目的启动,数据库经过一段时间的运行,最初的数据库设置,会与实际数据库运行性能会有一些差异,这时我们 就需要做一个优化调整. 数据库优化这个课题较大,可分为四大类: >主 ...
- PIE SDK 多数据源的复合数据集加载
1. 功能简介 GIS遥感图像数据复合是将多种遥感图像数据融合成一种新的图像数据的技术,是目前遥感应用分析的前沿,PIESDK通过复合数据技术可以将多幅幅影像数据集(多光谱和全色数据)组合成一幅多波段 ...
- Git本地有未提交文件,直接拉取远端最新版本
git pull = git fetch + git merge 1.修改不同的文件: 用户D和用户L在本地提交中修改了不同的文件,如果用户D将改动推送到服务器后,用户L再推送就会遇到非快进式推送错误 ...
- Loadsh 常用方法总结以及在vue中使用Loadsh
Loadsh 常用方法总结以及在vue中使用Loadsh Lodash 是一个一致性.模块化.高性能的 JavaScript 实用工具库.处理复杂数组,对比等可以直接采用该库,也方便快捷. 官方网站 ...
- 基于 ECharts 封装甘特图并实现自动滚屏
项目中需要用到甘特图组件,之前的图表一直基于 EChart 开发,但 EChart 本身没有甘特图组件,需要自行封装 经过一番鏖战,终于完成了... 我在工程中参考 v-chart 封装了一套图表组件 ...
- Java进程间通信学习
转自:https://www.iteye.com/blog/polim-1278435 进程间通信的主要方法有:(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共 ...
- WorkFlow一:WorkFlow基础配置
1.使用事物代码SWU3进入WF配置页. 2.展开第一个运行环境维护文件夹,选中第一个配置RFC目标,点击生成.完成后可点击运行按钮测试是否成功. 同上,挨个激活. 3.激活第二个文件夹‘维护环境定义 ...
- oracle 查询角色具有的权限
select * from dba_tab_privs where GRANTEE='角色名';
- mongo连接不上Timed out after 30000
本地连接mongo报错,错误代码为: Caused by: com.mongodb.MongoTimeoutException: Timed out after 30000 ms while wait ...