19 calloc 和 realloc 虚拟内存分配的调试

前言

 

前面提到了 malloc 虚拟内存分配相关的内容 

malloc 虚拟内存分配的调试(1)

malloc 虚拟内存分配的调试(2)

这里提 calloc 和 realloc, 这两个函数 虽然没有 malloc 使用频率那么高

但是 还是有很大的知名度的, 本文这里 我们来看一下 

calloc

此函数传入两个参数, 第一个参数是需要申请的 空间的数量, 第二个参数是 需要申请的空间的单位长度, 会申请 num 个大小为 size 的空间 

calloc 的处理就是申请 申请 num 个大小为 size 的空间, 然后将这部分空间 每一个字节 初始化为 0 

测试用例如下 

root@ubuntu:~/ClionWorkStations/HelloWorld# cat Test01Sum.c 
#include "stdio.h"

int main(int argc, char** argv) {

int x = 2;
int y = 3;
int z = x + y;

char *p1 = (char *)malloc(20);
char *p2 = (char *)malloc(20);

*p1 = '1';
*(p1+1) = '2';

free(p2);

void *p3 = calloc(2, 20);
printf("p1 : 0x%x - 0x%x \n", p1, p2);
printf("p3 : 0x%x - 0x%x \n", p3, p3);

}

先看一下 main 中的代码信息, 可以确定 我们断点是在 calloc(2, 20) 的地方 

传入的 num 为 2, elem_size 为 20 

这里计算出 总共占用的空间为 2 * 20 = 40 字节 

申请 40 字节的空间, 地址为 0x602050 

前面的 p1, p2 对应的 chunk 分别为 0x602000, 0x602020, 并且占用空间分别为 0x20 字节, top 中下一个空闲空间为 0x602040, 因此 这里用户拿到 mem/p3 是 0x602050 

接下来就是 将分配的空间 置为0 的操作了 

这里的优化很细节 

realloc 

realloc 如果更新之后的空间更小了
    如果拆分剩余的空间小于 32,则保留原样
    否则 将当前 chunk 拆分成两个 chunk
如果更新以后的空间更大
    则 如果当前是 top 最近的一块空间,尝试从 top 直接扩展,
    如果 下一个 chunk 有足够的空间,合并两个 chunk 然后再拆分需要的空间,
    否则  尝试分配空间
        如果分配空间为下一个 chunk 则合并当前 chunk
        复制原来的 chunk 的数据到 新的 chunk 的数据,然后 free 原来的 chunk

测试用例如下 

root@ubuntu:~/ClionWorkStations/HelloWorld# cat Test01Sum.c 
#include "stdio.h"

int main(int argc, char** argv) {

int x = 2;
int y = 3;
int z = x + y;

char *p1 = (char *)malloc(20);
char *p2 = (char *)malloc(20);

*p1 = '1';
*(p1+1) = '2';

free(p2);

void *p3 = realloc(p1, 10);
printf("p1 : 0x%x - 0x%x \n", p1, p2);
printf("p3 : 0x%x - 0x%x \n", p3, p3);

}


 

这是 realloc 更新之后空间 更小的情况 

1. 如果拆分之剩余的 chunk 小于 MINSIZE[32字节], 则当前 chunk 原封不动的返回 

2. 将当前 chunk 拆分成两个 chunk, 前面部分为保留的 chunk 返回, 后面部分的 chunk 更新 malloc 头, 然后 free 回收到空闲链表 

 这里的输出如下 

p1 : 0x602010 - 0x602030 
p3 : 0x602010 - 0x602010 

更新 realloc 指定空间为 30, 这是 realloc 更新之后空间 更大的情况 

这里 realloc 的是 p1, p1 对应的 chunk 为 0x602000 大小为 0x20 字节, 因此 next 为 0x602020, 对应的是 p2 

top 对应的是 0x602040

如果下一个 chunk 为 top, 并且空间足够, 则在当前 chunk 的基础上直接扩展 top, 并更新调整之后的 剩余的 chunk 的 malloc 头 

如果下一个 chunk 空闲, 并且空间足够, 则 merge 当前 chunk 和下一个 chunk, 然后尝试进行 chunk 的拆分[流程和上面 realloc 空间更小的情况一致]

否则 则尝试重新分配需要的空间 - 见下一张截图

尝试重新分配需要的空间

    如果分配到了下一个 chunk, 则和上面一样, merge 当前 chunk 和下一个 chunk, 然后尝试进行 chunk 的拆分[流程和上面 realloc 空间更小的情况一致]

    否则就是 将原有空间的数据拷贝到 重新分配的空间, 然后之后 回收掉原来的空间 

realloc(p1, 40) 就是这里的情况, 其他的情况可以自行测试 

p1 : 0x602010 - 0x602030 
p3 : 0x602050 - 0x602050 

因为空间的分配都依赖的是 malloc 的实现, 忽略掉 malloc 的实现之后 

这里的 空间分配简单得多了, 但是要理解更细节的东西, 还得理解 malloc 的分配规则 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/13297.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Obsidian中如何创作思维导图Mind-map

使用插件 obsidian-mind-map 1.直接在社区下载安装 设置快捷键或者在左侧竖形打开命令面板搜索关键字“mind”, 或者为了便于使用,设置快捷键,在设置-第三方插件中-选择快捷键 然后按下你想设置的快捷键就可以 我这里设置成了CtrlAltM ,M是…

虚拟数字人的3种驱动方式

虚拟数字人是由计算机程序所构建的具有人类特征的虚拟实体,目前的虚拟数字人经过了三代的更迭,划分每一代更迭的标准则是虚拟数字人的驱动方式。 一、虚拟数字人1.0:动画&CG驱动 虚拟数字人1.0就是目前我们所熟知的,比如&am…

LiveCharts2 初步认识

文章目录 1 LiveCharts2 是什么?2 LiveCharts2 可以做什么?3 简单使用LiveCharts2 ,实现动态曲线图 1 LiveCharts2 是什么? GitHub:https://github.com/beto-rodriguez/LiveCharts2 官网: https://lvchar…

C++ STL学习之【反向迭代器】

✨个人主页: 夜 默 🎉所属专栏: C修行之路 🎊每篇一句: 图片来源 A year from now you may wish you had started today. 明年今日,你会希望此时此刻的自己已经开始行动了。 文章目录 🌇前言&a…

分布式锁-Redisson

分布式锁 1、分布式锁1.1 本地锁的局限性1.1.1 测试代码1.1.2 使用ab工具测试(单节点)1.1.3 本地锁问题演示(集群情况) 1.2 分布式锁实现的解决方案1.3 使用Redis实现分布式锁(了解即可)1.3.1 编写代码1.3.2 压测 1.4 使用Redisson解决分布式锁1.4.1 实现代码1.4.1 压测1.4.2 可…

2 常见模块库(2)

2.5 复用器与分路器模块 Mux是一种用于将多个信号组合成一个信号的模块。Mux模块的名称来源于多路复用器(Multiplexer)。 使用Mux可以将多个输入信号组合成一个向量或矩阵,以便在模型中传递和处理。Mux模块可以接受任意数量的输入信号&#x…

什么是伪原创?SEO伪原创该怎么做

伪原创是指在原有的文章或内容基础上进行修改或调整,以产生看起来是全新内容的文章,但实际上并没有创造新的价值。多数情况下,伪原创的目的是为了在文章相对原创的情况下,提高搜索引擎的排名。 一、高质量伪原创 做好伪原创&#…

C语言从入门到精通第8天(分支结构if、else、switch的使用)

分支结构if、else、switch的使用 if语句if...else语句if...else嵌套if...else if...else语句switch语句 if语句 语法: if(表达式){ 语句; } 如果表达式为真,则执行{}里面的语句。如果为假,则不执行。示例代码: int m…

翻译国外文章-整篇文章的翻译

chatgpt翻译是专业的吗 ChatGPT是一种AI语言模型,它可以用来执行各种自然语言处理任务,包括翻译。然而,ChatGPT的翻译结果并不是专业的翻译,因为该模型并不是专为翻译任务训练的。 虽然ChatGPT的翻译质量相对较高,但…

全景视角下的世界探索——三维全景地图

引言:随着数字技术和虚拟现实技术的发展,三维全景地图已成为一种新型地图展示方式,深受人们的关注和喜爱。三维全景地图以其真实逼真、互动性强、展示效果好等特点,正在越来越多的领域得到应用。 三维全景地图的特点 1.真实逼真 …

考研计算机组成原理总结(7)

一.虚拟存储器 1.基本知识 主存和辅存共同构成了虚拟存储器,二者在硬件和系统软件的共同管理下工作。对于应用程序员而言,虚拟存储器是透明的。虚拟存储器具有主存的速度和辅存的容量。 2.基本概念 虚拟存储器将主存或辅存的地址空间统一编址&#x…

Excel中的表格批量生成word表格

场景:测试用例excel转word 我们在项目中,默认情况下是用我们的excel用例模版输出测试用例。但是有的项目中,会要求在word版本的测试计划或者测试报告中,写明测试用例。而我们的测试用例,有的项目有上千条,…

ChatGPT常见问题,Access denied的解决办法

今天,突然想登录一登录ChatGPT,提示 Access denied, You do not have access to chat.openai.com 怎么办? “Access denied You do not have access to chat.openai.com. The site owner may have set restrictions that prevent you from ac…

基于html+css的图片展示15

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

1026. 节点与其祖先之间的最大差值(4-19日

题目:给定二叉树的根节点 root,找出存在于 不同 节点 A 和 B 之间的最大值 V,其中 V |A.val - B.val|,且 A 是 B 的祖先。 (如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么…

2023年网络安全比赛--Windows渗透测试中职组(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 1.通过本地PC中渗透测试平台Kali对服务器场景20221219win进行系统服务及版本扫描渗透测试,并将该操作显示结果中1433端口对应的服务版本信息作为Flag值(例如3.1.4500)提交; 2.通过本地PC中渗透测试平台Kali对服务器场景202212…

车身控制模块BCM(Body Control Module)

1.BCM概述 车身控制模块BCM是高集成度的芯片。BCM的英文全称是Body Control Module。其控制对象是采用高灵敏度带唤醒及睡眠检测的高频收发器,实现车门车窗遥控上锁与开锁、电动后视镜、中控门锁、玻璃升降装置、车灯(远光灯、近光灯、位置灯、制动灯、转向灯、雾灯…

中国人民大学与加拿大女王大学金融硕士——在职读研该如何平衡学习与工作呢

边工作边考研,对于所有人来说都是个不小的挑战,每年都有大量在职生因为焦躁、压力而中途离场。学习时间碎片化,复习进度特别容易被工作上的事情所打断,再想“重新启动”就会很难。想要节省备考时间建议你读免联考的中外合作办学项…

第四章 法的效力

目录 第一节 法的效力概述 一、法的效力的意义二、法的效力的概念三、法的效力范围 第二节法的时间效力 一、法的生效时间二、法的失效时间三、法律溯及力 第三节法的空间效力 一、法的域内效力二、法的域外效力 第四节 法的对人效力 一、对人效力的原则二、我国法律的对人效力…

Vue|数据渲染

Vue 是如何将编译器中的代码转换为页面真实元素的?在Vue 中,自带了模板渲染,而模板的语法也非常简洁易懂。 精彩专栏持续更新↓↓↓ 微信小程序实战开发专栏 一. 数据渲染1.1 条件渲染v-ifv-show 1.2 列表渲染v-for 1.3 小结 一. 数据渲染 1.1 条件渲染 vue条件渲染…
最新文章