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. ...
随机推荐
- 转载-cookie和session的窃取
一.cookie的基本特性 如果不了解cookie,可以先到 wikipedia 上学习一下. http request 浏览器向服务器发起的每个请求都会带上cookie: GET /index.ht ...
- Leetcode(22)-括号生成
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "(()())& ...
- hdu 6242 Geometry Problem
Geometry Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Other ...
- Python 相关
循环使用迭代器 Python中使用for循环时,内置容器的默认循环都是有迭代器的.使用迭代器每次只会读出一小部分到内存,不断往后next. 通常建议在没有必要的情况下不使用for key,value ...
- C# 类 (6) -继承
继承 定义类的时候,public class Dog:Animal 表示 Dog 这个类是 继承自 Animal,冒号后面的是它的基类 继承后 的Dog 类,当调用Dog.Great() 的时候输出的 ...
- webpack-cli bugs All In One
webpack-cli bugs All In One Error: Cannot find module 'webpack-cli/bin/config-yargs' webpack version ...
- How to build a sortable table in native js?
How to build a sortable table in native/vanilla js? H5 DnD https://developer.mozilla.org/zh-CN/docs/ ...
- JavaScript this All In One
JavaScript this All In One js, this, bind, call, apply, new, function, arrow function, constructor f ...
- React Hooks +React Context vs Redux
React Hooks +React Context vs Redux https://blog.logrocket.com/use-hooks-and-context-not-react-and-r ...
- git include只包含某些文件
.gitignore: * # include !.gitignore !a.txt !dir2