【GLIBC 源码】 malloc内存分配

malloc内存分配

1. 内存分配策略由来

操作数据分配,在堆内存进行分配(因为栈存着私有数据段存全局,未初始化数据),那既然涉及到分配内存的使用,通过汇编角度的esp指针移动进行内存分配,无外乎就可同理可得,分配内存方式也可以通过指针分配,除了此方式,为了加快速度,也可推理得出可以采用mmap映射

  1. brk/sbrk指针:通过在堆内存用指针往高地址移动分配

  2. mmap映射:通过在堆里虚拟映射(非主分配区)

    激活mmap映射的阈值为128byte

    在这里插入图片描述

2. 代码结果验证

2.1 代码示例

这里我用如下代码进行debug调试,来验证sbrk,mmap

这里分别写了3个malloc的内存分配,为什么数字还不一样,128不是mmap的分配阈值么?怎么还用sbrk指针

先保留点好奇,后面会解答

#include <stdio.h>
#include <stdlib.h>

int main(){
   
   
	void *p = malloc(0);			// sbrk
	void *a = malloc(128 * 1024);	// sbrk
	void *q = malloc(132 * 1024);	// mmap
	printf("%p\n", p);
	printf("%p\n", a);
	printf("%p\n", q);
	return 1;
}

2.2 验证内存分配2种方式

sbrk指针分配的内存属于层级递增,而mmap属于在堆空间的高地址分配映射。

通过下面代码进行观察输出的地址信息

#include <stdio.h>
#include <stdlib.h>

int main(){
   
   
	void *p = malloc(0);
	void *q = malloc(128 * 1024);
	void *y = malloc(132 * 1024);
	printf("%p\n", p);
	printf("%p\n", q);
	printf("%p\n", y);
	return 1;
}

=======结果=======
0x1c1c010		// sbrk
0x1c1c030		// sbrk递增分配
0x7f5f4066a010	// mmap映射

3. 源码讲解

3.1 前置预备

​ 由于博主是Java Coder,这里只讲分配内存的直接关联代码,其余业务代码不会进行干涉。

​ 建议小伙伴自行下载sourceinsight新建glibc2.19的源码项目,方便对照eclipsedebug代码进行学习,如果对source insight导入源码,可看博主这篇文章Source Insight 读取源码使用入门

source insight如图

3.2 132kb的sbrk指针开辟的由来

⭐️本源码围绕[2.代码](# 2. 代码示例)进行debug讲解。机器是64位机,size_t对应是64位,8byte

从第一个malloc进行断点,进去malloc方法

这一小节围绕,malloc(0)代码debug

在这里插入图片描述

🚀1. 进行入参的大小转化成后续开拓内存的基石

将我们的入参0,转化为内存要求的大小,也就是下面代码checked_request2size(bytes, nb)

这里相关checked_request2size(bytes, nb)的具体实现,我写在了涉及源码调用api部分的下面,之后的代码也是同样如此,形式就如下

主流程源码

== == 涉及源码调用api部分 == ==

调用的api的具体实现

// 将请求大小转换为内部形式加上结构体的大小,获取校准和,以此获取扩展内存的大小的参数之一
// 这里进行nb的赋值,byte为传进来的值,目前第一个malloc传的是0
// 通过下方源码算出来,nb = 32byte
checked_request2size (bytes, nb);


// ===================涉及源码调用api部分=========================
// ===================如何计算的==========================
//  checked_request2size源码
#define checked_request2size(req, sz)
// 判断是否超出范围,超出结束进程,并添加错误信息
if (REQUEST_OUT_OF_RANGE (req)) {
   
   					      
      __set_errno (ENOMEM);						      
      return 0;								      
}
// 计算nb
(sz) = request2size (req);


// request2size源码
#define request2size(req)
// (0 + 8 + 15 < 32) ? 32 : ((8 + 15) & ~15) = 16
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?             
MINSIZE :                                                      
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

// SIZE_SZ源码
#ifndef INTERNAL_SIZE_T
#define INTERNAL_SIZE_T size_t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值