使用 malloc 在堆上分配内存的幕后花絮

Posted

技术标签:

【中文标题】使用 malloc 在堆上分配内存的幕后花絮【英文标题】:Behind the scene allocation of memory on heap using malloc 【发布时间】:2021-12-15 13:39:23 【问题描述】:

如果一个进程在堆上请求 1-24 个字节,为什么会有 32 个字节的差异?

如果一个进程在堆上请求 25-40 个字节,为什么会有 48 个字节的差异?

如果一个进程在堆上请求 41-56 字节,为什么会有 64 字节的差异?

最初的8bytes用来保存分配内存的长度

#include <stdio.h>
#include<stdlib.h>
int main()


  int size=41;
  char* c = (char*) malloc(size);//initial 8bytes used for length
  char* d = (char*) malloc(size);
  printf("a = %p\nb = %p\n difference is %d\n",c,d,d-c);
  free(c);
  free(d);



【问题讨论】:

是什么让您认为malloc 分配了您描述的 32、48 或 64 个字节?您是否正在查看它返回的指针之间的差异?如果两个指针相差 32 个字节,这并不意味着您可以在它们之间的分配中使用 32 个字节。很可能malloc 已将其自身数据的 8 个字节放在某处,以便在您将其传递给 free 时帮助它了解该内存块。 该信息应该在问题中。 【参考方案1】:

通常,函数 malloc 是这样实现的,它返回一块内存,它是段落大小的倍数,等于 16 字节(这个值可以等于 alignof(max_align_t) 的值)。也就是说,分配的内存必须为任何分配的对象对齐。

【讨论】:

为什么会这样?段落大小 == 16 字节的原因是什么? @mohammedyaqub 例如 sizeof( long double ) 等于 16。函数 malloc 不知道为哪种类型的对象分配内存。它的参数是 size_t 类型的值。但它应保证对齐。所以它使用最严格的对齐方式。

以上是关于使用 malloc 在堆上分配内存的幕后花絮的主要内容,如果未能解决你的问题,请参考以下文章

进程环境详解---堆分配mallocfree函数详解

C++数组在内存中的分配

在C中的堆上分配数组

Golang之变量去哪儿

内存分配

malloc和free的实现