malloc和free解析
malloc和free都是库函数,调用系统函数sbrk()来分配内存。除了分配可使用的内存以外,还分配了”控制“信息,这有点像内存池常用的手段。并且,分配的内存是连续的。
1. malloc
#include
void malloc_init()
{
last_valid_address = sbrk(0);//从操作系统分配内存
managed_memory_start = last_valid_address;//设置全局变量
has_initialized = 1;//全局变量,标示已经被初始化
}
上面那个函数,从名字中就可以理解,是一个初始化函数。什么时候来初始化呢?我想应该是在自己的程序里第一次调用这个函数时会调用到malloc_init()。如果存在多次调用,则会走下面这个函数:
这个是分配内存的控制块:
struct mem_control_block {
int is_available;//为0或1,等于1时表示可以重复使用
int size;//内存块的大小,包括本结构体在内
};
//清单 6. 主分配程序
void *malloc(long numbytes) {
void *current_location;//无类型指针,表示“当前块”,后面可以知道,它相关于链表访问时,操作当前节点的指针
struct mem_control_block *current_location_mcb;//“当前块”的mem_control_block指针 void *memory_location;//真正会返回的地址指针,即malloc()返回的
if(! has_initialized) {//如果没有初始化,则调用该函数,第一次肯定没有初始化,故,该函数应该会在第一次调用malloc()时使用
malloc_init();
}
numbytes = numbytes + sizeof(struct mem_control_block);//调整传进来的大小,包括mem_control_block这个结构体大小
memory_location = 0;//设置为0 current_location = managed_memory_start;//managed_memory_start为全局变量,保存一块连续内存的起始位置。它第一次在malloc_init()中设置
while(current_location != last_valid_address)//这里开始“遍历”,从managed_memory_start直到last_valid_address
{
current_location_mcb =(struct mem_control_block *)current_location;//无类型指针转换为mem_control_block指针
if(current_location_mcb->is_available)//如果当前块可用。这里is_available为1表示可用
{
if(current_location_mcb->size >= numbytes)//如果当前块的大小足够使用的
{
current_location_mcb->is_available = 0;//标示当前块已经被“占用”了
break;//跳出while表示找到了可用的块,其实是为了节约内存空间
}
}
current_location = current_location +current_location_mcb->size;//走到这里表示“当前块”不可用,current_location往后走“一块”的大小。
} //没有找到,则开辟新的内存
if(! memory_location)
{
sbrk(numbytes);//调用系统函数,分配内存 memory_location = last_valid_address;//这里的memory_location等于last_valid_address,我觉得应该是sbrk()这个系统调用所分配的新的块是与当前块连续的,同时,last_valid_address指向的是所有可用内存的“最后的边界”
last_valid_address = last_valid_address + numbytes;//更新这个“边界” current_location_mcb = memory_location;//设置指针和结构体的值
current_location_mcb->is_available = 0;
current_location_mcb->size = numbytes;
} memory_location = memory_location + sizeof(struct mem_control_block);//指针“跳过”结构体大小,指向真正的可用内存,也就是malloc返回的指针 return memory_location;
}
2.free
void free(void *firstbyte) {
struct mem_control_block *mcb;
mcb = firstbyte - sizeof(struct mem_control_block);//指针后退,退过mem_control_block的大小
mcb->is_available = 1;//标示该“块”可用 return;
}
free函数很简单,就是将当前可用指针后退到真正的“块”的起始位置,再设置“块”为可用(is_available=1),可见free也并不是把内存真正的释放掉了,只是作为标记。为什么要这样设置?从代码中可用看到,这样设置完之后,如果下次再调用malloc,将对所有的块进行搜索,找到这样一个可用的。这样的好处是什么?节约内存!相当于内存池里的重复利用。
参考资料:http://lklkdawei.blog.163.com/blog/static/32574109200881445518891/
http://blog.csdn.net/eroswang/article/details/4265024
malloc和free解析的更多相关文章
- ios开发中字符串的常用功能总结
1.分割字符串 NSString * str1 = @"123/456"; NSArray * arr1 = [str1 componentsSeparatedByString:@ ...
- 深入C++ new/delete,malloc/free解析
深入C++ new/delete,malloc/free解析 1.malloc与free是C++/C语言的标准库函数.new/delete是C++的运算符. 它们都可用于申请动态内存和释放内存 2.对 ...
- malloc,calloc,realloc函数用法,原理及不同解析
https://blog.csdn.net/lixungogogo/article/details/50887028 一.malloc malloc在MSDN中原型为: void *malloc( s ...
- ZH奶酪:C语言中malloc()和free()函数解析
1.malloc()和free()的基本介绍 (1)函数原型及说明 void *malloc(long NumBytes) 该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败 ...
- [httpserver]如何解析HTTP请求报文
这个http server的实现源代码我放在了我的github上,有兴趣的话可以点击查看哦. 在上一篇文章中,讲述了如何编写一个最简单的server,但该程序只是接受到请求之后马上返回响应,实在不能更 ...
- iOS开发之Alamofire源码解析前奏--NSURLSession全家桶
今天博客的主题不是Alamofire, 而是iOS网络编程中经常使用的NSURLSession.如果你想看权威的NSURLSession的东西,那么就得去苹果官方的开发中心去看了,虽然是英文的,但是结 ...
- iOS之数据解析时<null>的处理
在iOS开发过程中经常需要与服务器进行数据通讯,JSON就是一种常用的高效简洁的数据格式. 问题: 在项目中,一直遇到一个坑的问题,程序在获取某些数据之后莫名崩溃.原因是:由于服务器的数据库中有些字段 ...
- Pugixml一种快速解析XML文件的开源解析库
Pugixml是一个轻量级的C++ XML开源解析库,DOM形式的解析器.接口和丰富的遍历和修改操作,快速的解析,此外支持XPath1.0实现数据查询,支持unicode编码: 使用Pugixml可通 ...
- Python2 基本数据结构源码解析
Python2 基本数据结构源码解析 Contents 0x00. Preface 0x01. PyObject 0x01. PyIntObject 0x02. PyFloatObject 0x04. ...
随机推荐
- VS2010的单元测试(二)
四.附加测试属性 附加测试属性,在默认生成的测试代码是使被注释掉的,取消注释就可以使用. 例如,要在执行测试前,输出测试开始时间,在执行测试后,输出测试结束时间.代码如下: [ClassInitial ...
- go免杀初探
0x01 go免杀 由于各种av的限制,我们在后门上线或者权限持久化时很容易被杀软查杀,容易引起目标的警觉同时暴露了自己的ip.尤其是对于windows目标,一个免杀的后门极为关键,如果后门文件落不了 ...
- 涂颜色的RPG问题
长度为n的方格,刷3种颜色的颜料,相邻的方格颜料颜色不能相同,且首尾方格颜色不能相同.每个方格必须涂色.计算一共有多少种涂色方式. 解题思路:(1)f(1)=3,f(2)=6,f(3)=6 (2)如果 ...
- Os-hackNos-1(drupal7+suid提权)
一.信息收集 得到 ip是 192.168.56.101 , 端口开启了22和80,扫目录发现drupal 7 访问一下呢 在exploit-db上面搜索到存在相关的漏洞,而且是用直接上msf 使用第 ...
- SpringBoot进阶教程(七十)SkyWalking
流行的APM(Application Performance Management工具有很多,比如Cat.Zipkin.Pinpoint.SkyWalking.优秀的监控工具还有很多,其它比如还有za ...
- 如何在Python 中使用UTF-8 编码 && Python 使用 注释,Python ,UTF-8 编码 , Python 注释
如何在Python 中使用UTF-8 编码 && Python 使用 注释,Python ,UTF-8 编码 , Python 注释 PIP $ pip install beauti ...
- Promise console.log All In One
Promise console.log All In One 同步事件/异步事件 微任务/宏任务 js 事件循环原理 先执行 同步事件 在执行,异步事件的所有微任务队列,按照时间顺序 最后执行,异步事 ...
- Flutter 删除AppBar的返回icon
设置automaticallyImplyLeading: false即可,替换可以修改"leading"参数 ... appBar: AppBar( automaticallyIm ...
- 「NGK每日快讯」2021.2.3日NGK公链第92期官方快讯!
- 为什么ElasticSearch比MySQL更适合全文索引
熟悉 MySQL 的同学一定都知道,MySQL 对于复杂条件查询的支持并不好.MySQL 最多使用一个条件涉及的索引来过滤,然后剩余的条件只能在遍历行过程中进行内存过滤,对这个过程不了解的同学可以先行 ...