为什么在分配单个字节时地址不连续?

时间:2013-01-30 23:59:10

标签: c unix alignment malloc

我按如下方式动态分配内存:

char* heap_start1 = (char*) malloc(1);
char* heap_start2 = (char*) malloc(1);

当我按照以下方式执行printf时,地址不是连续的。

printf("%p, %p \n",heap_start1,heap_start2);

结果:

   0x8246008, 0x8246018

正如您所看到的那样,有一个15字节的额外内存被进行了碎片整理。这绝对不是因为词对齐。这种奇特的对齐背后有什么想法吗?

提前致谢!

如果重要的话,我在linux中使用gcc。

4 个答案:

答案 0 :(得分:6)

glibc的malloc,对于小于16字节的小内存分配,只需将内存分配为16字节。这是为了防止在释放此内存时出现外部碎片,其中可用内存块太小而无法在一般情况下用于执行新的malloc操作。

malloc分配的块也必须足够大,以存储在存储空闲块的数据结构中跟踪它所需的数据。

这种行为在增加内部碎片的同时,减少了整个系统的整体碎片。

<强>来源: http://repo.or.cz/w/glibc.git/blob/HEAD:/malloc/malloc.c (特别是阅读第108行)

/*
...
Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
...
*/

此外,glibc中malloc调用返回的所有地址都与:2 * sizeof(size_t)字节对齐。对于32位系统(例如你的系统),这是64位,对于64位系统,这是128位。

答案 1 :(得分:4)

至少有三个可能的原因:

  • malloc需要为所有原始类型生成适当对齐的内存。 SSE指令的数据需要128位对齐。 (您的平台可能还有其他128位原始类型,目前我不会遇到这种类型。)

  • malloc的典型实现涉及“过度分配”,以便为快速free存储簿记信息。不确定Linux上的GCC是否会这样做。

  • 可能正在分配guard bytes以便检测缓冲区溢出等等。

答案 2 :(得分:0)

如果要分配连续的地址,则应在同一个malloc上分配它们

char *heap_start1, *heap_start2;
heap_start1 = (char*) malloc(2 * sizeof(char));
heap_start2 = heap_start1 + 1;

答案 3 :(得分:0)

malloc保证返回的内存与任何基本类型正确对齐。此外,可以使用一些保护字节填充内存块以检查内存损坏,这取决于设置。