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解析的更多相关文章

  1. ios开发中字符串的常用功能总结

    1.分割字符串 NSString * str1 = @"123/456"; NSArray * arr1 = [str1 componentsSeparatedByString:@ ...

  2. 深入C++ new/delete,malloc/free解析

    深入C++ new/delete,malloc/free解析 1.malloc与free是C++/C语言的标准库函数.new/delete是C++的运算符. 它们都可用于申请动态内存和释放内存 2.对 ...

  3. malloc,calloc,realloc函数用法,原理及不同解析

    https://blog.csdn.net/lixungogogo/article/details/50887028 一.malloc malloc在MSDN中原型为: void *malloc( s ...

  4. ZH奶酪:C语言中malloc()和free()函数解析

    1.malloc()和free()的基本介绍 (1)函数原型及说明 void *malloc(long NumBytes) 该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败 ...

  5. [httpserver]如何解析HTTP请求报文

    这个http server的实现源代码我放在了我的github上,有兴趣的话可以点击查看哦. 在上一篇文章中,讲述了如何编写一个最简单的server,但该程序只是接受到请求之后马上返回响应,实在不能更 ...

  6. iOS开发之Alamofire源码解析前奏--NSURLSession全家桶

    今天博客的主题不是Alamofire, 而是iOS网络编程中经常使用的NSURLSession.如果你想看权威的NSURLSession的东西,那么就得去苹果官方的开发中心去看了,虽然是英文的,但是结 ...

  7. iOS之数据解析时<null>的处理

    在iOS开发过程中经常需要与服务器进行数据通讯,JSON就是一种常用的高效简洁的数据格式. 问题: 在项目中,一直遇到一个坑的问题,程序在获取某些数据之后莫名崩溃.原因是:由于服务器的数据库中有些字段 ...

  8. Pugixml一种快速解析XML文件的开源解析库

    Pugixml是一个轻量级的C++ XML开源解析库,DOM形式的解析器.接口和丰富的遍历和修改操作,快速的解析,此外支持XPath1.0实现数据查询,支持unicode编码: 使用Pugixml可通 ...

  9. Python2 基本数据结构源码解析

    Python2 基本数据结构源码解析 Contents 0x00. Preface 0x01. PyObject 0x01. PyIntObject 0x02. PyFloatObject 0x04. ...

随机推荐

  1. Leetcode(19)-删除链表的倒数第N个节点

    给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 ...

  2. spyder import tensorflow

    之前安装了tensorflowgpu,但是在spyder中import会失败. 原因是因为新建了环境,要activate tensorflow-gpu进入安装了tensorflow 的环境才可以imp ...

  3. 操作系统 part3

    1.操作系统四特性 并发:一个时间段,多个进程在宏观上同时运行 共享:系统中的资源可以被多个并发进程共同使用(互斥共享,同时共享) 虚拟:利用多道程序设计,利用时分复用(分时系统)和空分复用(虚拟内存 ...

  4. 牛客多校第三场J LRU management(双向链表)题解

    题意: 给一个长度为\(m\)的队列,现给定以下操作: \(opt=0\),插入一个串,如果不在队里直接插入栈尾,如果超出\(m\)删队首:在队里就拿出来重新放到队尾,返回\(v\)值. \(opt= ...

  5. Hexo-域名设置+收录

    Hexo-域名设置+Github域名加速+网址收录 Github.Gitee绑定域名,然后进行网址收录. 不想购买域名也完全可以进行网址收录. 购买阿里云域名 1.进入阿里云域名网站 2.进入价格详情 ...

  6. Kafka 博文索引

    博文索引 KafkaBroker 简析 KafkaConsumer 简析 KafkaProducer 简析 KafkaMirrorMaker 的不足以及一些改进 Kafka 简介 数据是系统的燃料,系 ...

  7. 海 鱼立 鲷 & 海䲞鲷

    海 鱼立 鲷 & 海䲞鲷 䲞 lì 鲷 diāo 二长棘鲷 二长棘鲷(学名:Parargyrops edita)为辐鳍鱼纲鲈形目鲷科二长棘鲷属的鱼类,俗名板鱼.䲞鱼.盘仔鱼.立花.赤鬃.长鳍. ...

  8. Axios all in one

    Axios all in one https://github.com/axios/axios#example GET const axios = require('axios'); // Make ...

  9. js showOpenFilePicker showSaveFilePicker showDirectoryPicker API

    选择文件,获取文件句柄 btn.addEventListener("click", async (e) => { try { const hFiles = await win ...

  10. 聚焦 2021 NGK 新加坡区块链技术峰会,探讨DeFi未来新生态!

    2021年1月31日14时,备受行业关注的"2021 NGK 新加坡区块链技术峰会"如期举行.本次峰会由NGK官方主办,以"DeFi"为主题,探讨了区块链技术革 ...