malloc 源码_malloc源码

malloc 源码_malloc源码malloc底层原理学习本文主要整理我最近搜集到的各路资料,看了别人的代码并且加上一些个人的理解。首先先重新审视堆这个数据结构。在程序中,堆用于动态分配和释放程序所使用的对象。在以下情况中调用堆操作:1.事先不知道程序所需对象的数量和大

malloc底层原理学习
  本文主要整理我最近搜集到的各路资料,看了别人的代码并且加上一些个人的理解。

  首先先重新审视堆这个数据结构。

  在程序中,堆用于动态分配和释放程序所使用的对象。在以下情况中调用堆操作:

  1.事先不知道程序所需对象的数量和大小。

  2.对象太大,不适合使用堆栈分配器。

  堆使用运行期间分配给代码和堆栈以外的部分内存。

  然后是虚拟存储器:

  基于局部性原理,应用程序在运行之前,没有必要全部装入内存,仅须将那些当前要运行的部分页面或段先装入内存便可运行,其余部分暂留在盘上。

  所谓虚拟存储器:是指具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统,其逻辑容量由内存容量和外存容量之和所决定,其运行速度接近于内存速度,而每位的成本却又接近于外存。

  使用过c语言的都知道malloc是一个动态分配内存的函数,还可以通过free释放内存空间。malloc 函数返回一个指针,指向大小(至少)为 size 字节的存储器块,这个块可能会包含在这个块内的任何数据对象类型做对齐。

  malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。动态存储器分配器维护着一个进程的虚拟存储器区域,称为堆。

  这个函数要实现的功能是在系统中分配一段连续的可用的内存,具体有如下要求:malloc分配的内存大小至少为size参数所指定的字节数malloc的返回值是一个指针,指向一段可用内存的起始地址多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉malloc应该尽快完成内存分配并返回(不能使用NP-hard的内存分配算法)实现malloc时应同时实现内存大小调整和内存释放函数(即realloc和free)

  对于malloc更多的说明可以在命令行中键入以下命令查看:

  如果我们想分析一下malloc的源码,这其实不是一会就能看懂的,但是我们可以讨论一下malloc的简单实现。

  为什么要自己编写malloc()函数:在嵌入式编程中,内存的大小都是有限的,考虑到成本问题,我们尽量包含少一点的函数库,减小不必要的浪费。

  成功时,返回所分配存储空间的起始地址;返回值类型为void*,在C语言中可以把void*直接付给具体的类型,但是在C++中必须进行强制类型转换

  失败时(内存不足时)返回NULL

  size为0时,返回的指针不是NULL;但是除了free,别的地方不要使用这个指针。

  malloc实际分配的内存会大于我们需要的size。主要由两方面因素决定:

  1、字节对齐。会对齐到机器最受限的类型(具体的实现因机器而异)。

  2、“块头部信息”。每个空闲块都有“头部”控制信息,其中包含一个指向链表中下一个块的指针、当前块的大小和一个指向本身的指针。为了简化块对齐,所有块的大小都必须是头部大小的整数倍,且头部已正确对齐。

  以下为《C程序设计语言》中给出的通过union进行的头部实现,其中假定机器的受限类型为long。

  说明:

  (1)实际分配的内存块将多一个单元,用于头部本身。实际分配的块的大小被记录在头部的size字段中。

  (2)size字段是必须的,因为malloc函数控制的块不一定是连续的,这样就不能通过指针算术运算计算其大小。

  (3)malloc返回的是空闲块的首地址,而不是首地址。

  malloc/free的实现过程:

  1、空闲存储空间以空闲链表的方式组织(地址递增),每个块包含一个长度、一个指向下一块的指针以及一个指向自身存储空间的指针。( 因为程序中的某些地方可能不通过malloc调用申请,因此malloc管理的空间不一定连续。)

  2、当有申请请求时,malloc会扫描空闲链表,直到找到一个足够大的块为止(首次适应)(因此每次调用malloc时并不是花费了完全相同的时间)。

  3、如果该块恰好与请求的大小相符,则将其从链表中移走并返回给用户。如果该块太大,则将其分为两部分,尾部的部分分给用户,剩下的部分留在空闲链表中(更改头部信息)。因此malloc分配的是一块连续的内存。

  4、释放时,首先搜索空闲链表,找到可以插入被释放块的合适位置。如果与被释放块相邻的任一边是一个空闲块,则将这两个块合为一个更大的块,以减少内存碎片。

  malloc:

  free:

  这里仅仅讨论了c语言的具体实现,还有一些ptmalloc、tcmalloc和jemalloc还没讨论,有时间会写相关的。

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

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

(0)
上一篇 2024年 5月 30日 08:10
下一篇 2024年 5月 30日 08:21

相关推荐

关注微信