堆利用

这里给哪些初学者学堆的一些简单的讲解,

什么是堆?
在程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未知的内存。堆其实就是程序虚拟地址空间的一块连续的线性区域,它由低地址向高地址方向增长。我们一般称管理堆的那部分程序为堆管理器。
堆管理器处于用户程序与内核中间,主要做以下工作
响应用户的申请内存请求,向操作系统申请内存,然后将其返回给用户程序。同时,为了保持内存管理的高效性,内核一般都会预先分配很大的一块连续的内存,然后让堆管理器通过某种算法管理这块内存。只有当出现了堆空间不足的情况,堆管理器才会再次与操作系统进行交互。
管理用户所释放的内存。一般来说,用户释放的内存并不是直接返还给操作系统的,而是由堆管理器进行管理。这些释放的内存可以来响应用户新申请的内存的请求。
Linux 中早期的堆分配与回收由 Doug Lea 实现,但它在并行处理多个线程时,会共享进程的堆内存空间。因此,为了安全性,一个线程使用堆时,会进行加锁。然而,与此同时,加锁会导致其它线程无法使用堆,降低了内存分配和回收的高效性。同时,如果在多线程使用时,没能正确控制,也可能引起内存分配和回收的正确性。Wolfram Gloger 在 Doug Lea 的基础上进行改进使其可以支持多线程,这个堆分配器就是 ptmalloc 。在 glibc-2.3.x. 之后,glibc 中集成了ptmalloc2。
目前 Linux 标准发行版中使用的堆分配器是 glibc 中的堆分配器:ptmalloc2。ptmalloc2 主要是通过 malloc/free 函数来分配和释放内存块。
需要注意的是,在内存分配与使用的过程中,Linux有这样的一个基本内存管理思想,只有当真正访问一个地址的时候,系统才会建立虚拟页面与物理页面的映射关系。 所以虽然操作系统已经给程序分配了很大的一块内存,但是这块内存其实只是虚拟内存。只有当用户使用到相应的内存时,系统才会真正分配物理页面给用户使用。
x64位
在这里插入图片描述堆是从低地址向高地址
kernel space是内核空间
堆是增删查改
在这里插入图片描述malloc的介绍
**/
malloc (size_t n)
返回一个指针,指向新分配的至少n个字节的块,或null
如果没有可用的空间。此外,在失败时,errno是
在ANSI C系统上设置ENOMEM。
如果n为零,malloc返回一个最小大小的块。(最低
大小在大多数32位系统上是16字节,在64位系统上是24或32字节
系统)。在大多数系统中,size_t是无符号类型,所以调用
用否定的论点会被解释为要求大量的钱
空间,这往往会失败。n的最大支持值
系统之间是不同的,但在所有情况下都小于t
**/
上面可以看出:
malloc函数返回对应大小字节的内存块的指针,此外,该函数还可以对一些异常情况进行的处理,
当n=0时,返回当前的系统允许的堆的最小内存块,
当n为负数时,由于在大多数系统上,size_t是无符号数,这里的程序就会申请很大的内存空间,但这系统是报错的,因为系统没有那么内存可以分配。

chunk是什么呢
是堆的最小操作单元,不可分割单元,是最基础,
chunk就是一个结构体
在这里插入图片描述prev_size和size是chunk头(top chunk)
上面的prev_size = 8byte
size代表当前chunk的大小,包括chunk头
在这里插入图片描述size of previous对应是上面chunk的prev_size
在这里插入图片描述在这里是二进制代表标志位
malloc是堆的分配作用
而free是堆的回收作用
在这里插入图片描述了解一个对齐,是一个地址对齐
size_t = 8字节,

接下来编译:
写好的代码,用subl可以查看源码,
在这里插入图片描述在malloc,在堆申请0x10空间
在这里插入图片描述接下来就用gdb调试

b malloc
r
heap
vmmap查看内存权限

在这里插入图片描述会报错,在malloc没有分配空间
在这里插入图片描述如果继续c的话,会下在下一个断点,第一的malloc已经分配了
这个我下去heap,这个会出错,就改了一下源码,在前面加了,sleep(0.1),
这就需要重新编译一下:

gcc 文件的.c -o 文件名()
接下去就要断在sleep上面,b sleep
c继续运行
heap

在这里插入图片描述c继续运行后heap下,用heap查看,可以看出,堆没有被初始化

就可以看到prev_size=0x0
size=0x21是申请的空间
真正的size=chunk头+申请的大小=0x21

在这里插入图片描述size是top chunk地址
在这里插入图片描述分析chunk x/4gx 地址 /查看内存信息
在这里插入图片描述
真正的size = chunk+申请大小 ///上面的哪个0x21
这里chunk是0x10 ,malloc是0x10,
0x1是fasbin的inyou位置于1(也就是下面图的p)
标志位p是用二进制表示,
当为1是chunk使用中
当为0时chunk没有使用中在这里插入图片描述在这里插入图片描述chunk格式
在这里插入图片描述fd和bk是在chunk被使用
在这里插入图片描述fd和bk是链表,(指向的是前一个链表和后一个指针)
ps:fasbin是单链,smalloc是双链,
fd指向下一个空闲的chunk
bk指向上一个空闲的chunk
单双链表的最小操作单元是节点(note)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值