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. ...
随机推荐
- redis运维与开发笔记
- range()函数的使用、while循环、for-in循环等
一.range()函数 用于直接生成一个整数序列 创建range对象的三种方式: (1)range(stop) 创建一个(0,stop)之间的整数序列,步长为1 (2)range(start,s ...
- Pycharm缺少环境变量+无法获取libcudnn.so.6
在终端输入: echo LD_LIBRARY_PATH, 并将其内容 添加至Pycharm的 run -> Edit configuration -> Environment variab ...
- export html to canvas image
export html to canvas image canvas.toDataURL https://developer.mozilla.org/en-US/docs/Web/API/HTMLCa ...
- autocode & API
autocode & API https://autocode.com/app/ https://autocode.com/lib/ api-service https://dashboard ...
- Interview Questions All In One
Interview Questions All In One web fullstack System Design Operating System Object-Oriented Design O ...
- bye MVA
bye MVA https://mva.microsoft.com/
- how to get selected option text in javascript
how to get selected option text in javascript refs https://developer.mozilla.org/en-US/docs/Web/API/ ...
- post upload file & application/x-www-form-urlencoded & multipart/form-data
post upload file application/x-www-form-urlencoded & multipart/form-data https://stackoverflow.c ...
- 一次 MySQL 线上死锁分析实战
关键词:MySQL Index Merge 前言 MySQL 的锁机制相信大家在学习 MySQL 的时候都有简单的了解过,那既然有锁就必定绕不开死锁这个问题.其实 MySQL 在大部分场景下是不会存在 ...