ezikra3xgf464093973227.gif
点击上方蓝色字体,关注我们
以下是我的一些看法。
malloc 和 free 实际上是依赖于 C 库和操作系统提供的内存管理机制,它们基于特定的数据结构和算法来管理动态分配的内存。
1
malloc 内存分配的实现
当你调用 malloc 分配内存时,C 运行时库(如 glibc)会从堆中分配一块内存。在这个过程中,分配器会维护一个内部的 “自由链表”(free list)或其他数据结构来追踪哪些内存块是空闲的,哪些是已分配的。
当需要分配内存时,分配器会从自由链表中找到合适大小的空闲块,然后将这块内存返回,并在链表中更新其状态。
2
free 释放内存的原理
在 free 时,分配器需要知道内存块的起始地址以及它的大小,以便将其标记为空闲并重新加入自由链表。你提到的“如何知道要释放的内存大小”是一个关键问题,这确实依赖于内存分配器内部的数据结构。
通常分配器会在每个分配的内存块前增加一个 “头部”(header),这个头部存储了该内存块的元信息,包括分配的大小和状态(空闲或已分配)。因此,当你传递指针 p 给 free 时,分配器可以通过 p 之前的头部信息找到整个块的大小,然后正确释放该块。
3
为什么 free(p + 6) 仍然能释放整个块
在 C 中,标准库实现中并不支持直接释放偏移后的地址(如 p + 6)。尝试调用 free(p + 6) 实际上会导致未定义行为,具体表现取决于实现,但通常会导致程序崩溃或产生错误。
4
数据结构和性能优化
典型的内存分配器使用 双向链表 或 分离链表 来维护空闲和已分配的内存块,以便快速找到和释放内存。自由链表通常按大小分段存储,以便在释放时找到最合适的块,减少碎片化。
在一些高级分配器(如 tcmalloc 或 jemalloc)中,使用了更加复杂的数据结构,例如 哈希表或树状结构(如红黑树)来管理和分配内存。这种结构优化了查找速度,并通过不同大小的块分区降低了碎片化程度。
yq0nci3fyq264093973327.jpg
rhxkbiwolze64093973427.gif
点击阅读原文,更精彩~ |