malloc 初始值_malloc怎么用

malloc 初始值_malloc怎么用内存管理:malloc入口和关键数据结构前文已经介绍了堆管理的背景知识还有相关算法:虚拟地址空间和堆隐式空闲链表显式空闲链表从本文开始来分析一下glibc的malloc实现,其中所列的代码都经过精简和修改,现在glibc的最新版本是2.33(htt

内存管理:malloc入口和关键数据结构   前文已经介绍了堆管理的背景知识还有相关算法:虚拟地址空间和堆隐式空闲链表显式空闲链表   从本文开始来分析一下glibc的malloc实现,其中所列的代码都经过精简和修改,现在glibc的最新版本是2.33(https://www.gnu.org/software/libc/),实际的代码太多,不能全部列出,只能尽量简化   一、函数入口   直接在glibc种查找malloc函数的话是找不到的,因为malloc只是一个别名,真正的实现函数名是__libc_malloc:   其中strong_alias是一个宏:   __typeof是GNU C(它是标准C的扩展,不严格的说,像ANSI C、ISO C、Standard C、C89、C99都是标准C以不同时期和角度的叫法)中的特性,作用和C++11新出现的decltype有点像,更多细节可以参考GCC10.1的这部分文档:https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes   __attribute__是一个编译属性,它也是GNU C特色之一,用于向编译器描述特殊的标识、错误检查或高级优化。它可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute),上面代码设置的是变量属性(设置变量属性细节可参考GCC10.1的文档:https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes),语法格式为:   二、malloc_chunk数据结构   malloc中用到的chunk数据结构名称是malloc_chunk,这个数据结构非常重要,是malloc管理堆的基本数据结构,具体定义为:   字段的注释大概说明了这个字段的含义,后面再用图示的方法来详细说下这个数据结构。   三、free chunk   把上面malloc_chunk数据结构直接图形化,结果就是free chunk的示意图,关于allocated chunk,后面会再讲到,这里先展示free chunk:
malloc 初始值_malloc怎么用
malloc 初始值_malloc怎么用图1:free chunk   注意上面图1的mchunk_prev_size这个区域类似于前文隐式空闲链表和显式空闲链表中的footer,只是malloc代码把footer部分放到了header之前,后面再具体说为什么。   再来看mchunk_size区域中的A、M、P三个flag的含义,这三个bit flag同样对应前文显式空闲链表中的af flag,只是前文只用了一个bit,这里三个bit全用了,具体的含义如下:A:NON_MAIN_ARENA的缩写,指所用arena是不是main arena的flag,关于arena在虚拟地址空间和堆一文中已经介绍过,这里不再赘述M:IS_MMAPPED的缩写,指所用chunk是不是经由mmap分配所得P:PREV_INUSE的缩写,指当前chunk的前一个chunk是不是allocated chunk,是的话这个bit为1,否则为0   再看fd、bk这两个字段,这个和前文显式空闲链表中的意思相同,分别用来指向forward方向和backward方向的第一个free chunk。fd_nextsize和bk_nextsize也是两个指针,这两个指针只在large chunk中会用到。   四、allocated chunk   先注意一下上面图1注明了是free chunk,因为malloc_chunk中的这些字段,在chunk是free状态的时候按照图1所列字段解释,在chunk状态是allocated的时候,fd、bk、fd_nextsize、bk_nextsize这些字段全部变成用来存放payload(有效数据)   还有mchunk_prev_size这个字段也要注意一下,它有两种解释:在previous chunk是free chunk的时候:这个字段的值是前一个chunk的size在previous chunk是allocated chunk的时候:这个字段里的值可能是前一个chunk的payload(有效数据)   根据前面的这些说明,allocated chunk结构如下图:
malloc 初始值_malloc怎么用
malloc 初始值_malloc怎么用图2:allocated chunk   特别需要注意的是,在上面图2,红色部分实际上是next chunk的mchunk_prev_size区域,但是在当前chunk是allocated状态时,next chunk的mchunk_prev_size部分也成了current chunk的payload区域。   这里顺便说一下为什么要把前文显式空闲链表介绍的footer放到了chunk的header之前,之前说过,chunk size和malloc的返回指针mem都要能被8整除,把footer放到header之前并变为mchunk_prev_size字段,这样在mem指针之前就有了8个字节的数据,这样只要当前chunk的开始指针8字节对齐,那么mem指针自然也就8字节对齐,这样处理起来会简单一些,带来的代价就是需要做这些解释。   五、chunk组合情况   本系列接下来所做的分析如果没有特殊说明,都是默认图1的A、M两个bit的flag的值为0,意思就是只main arena和所有的chunk都是经过brk/sbrk分配得到。之所以这样做是因为glibc中malloc的实现非常复杂,考虑了各种情况(包括跨平台、不同版本、多线程支持等),如果文章不做取舍,很难把主线讲清楚,还请大家见谅。   前面讲了free chunk和allocated chunk,这两种chunk组合在一起会产生四种情况:allocated+allocatedallocated+freefree+allocatedfree+free:因为两个free chunk会被merge,通常这种情况不存在,源码里有一种特殊情况,这里暂且不说   下面用图示的方法展示上面1、2、3三种情况的两个chunk的相接部分,这样更容易理解,图中忽略fd_nextsize和bk_nextsize这两个特殊字段:
malloc 初始值_malloc怎么用
malloc 初始值_malloc怎么用图3:allocated+allocated   上面图3需要注意的是第二个chunk的mchunk_prev_size区域已经变成了第一个chunk的payload,第二个chunk的P(PREV_INUSE) flag也为1,两个mem指针也必须是8字节对齐。
malloc 初始值_malloc怎么用
malloc 初始值_malloc怎么用图4:allocated+free   上面图4值得注意的是下面的free chunk中的fd、bk这些指针字段是有效字段了,也会指向相应的其它free chunk,这个图中没有画出
malloc 初始值_malloc怎么用
malloc 初始值_malloc怎么用图5:free+allocated   上面图5需要注意的是下面的chunk的mchunk_prev_size字段是有效字段,存储了上面free chunk的chunk size,同时下面chunk的P(PREV_INUSE) flag也被设为0   六、heap_info和malloc_state   它们是堆管理的核心全局数据结构,之前在虚拟地址空间和堆一文中简单提了一下,这里再来说一遍,因为这两个数据结构太重要了,尤其是malloc_state,后续的文章在用到里面的成员的时候再详细说,大家可以先看下定义了解个大概:   七、小结   文章主要介绍了malloc_chunk这个重要的数据结构,也简单提了下heap_info和malloc_state,整个malloc的代码都会以这几个数据结构为基础,限于篇幅,本文先写到这,后续文章继续分析malloc的代码实现。

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/56295.html

(0)
上一篇 2024年 8月 31日
下一篇 2024年 8月 31日

相关推荐

关注微信