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

我dynamic地分配内存如下:

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

当我做printf如下令人惊讶的地址是不连续的。

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

结果:

  0x8246008, 0x8246018 

正如你所看到的,有15个字节的额外的内存是残留碎片整理。 这绝对不是因为字alignment。 任何想法背后这个奇特的路线?

提前致谢!

如果有问题,我正在linux中使用gcc。

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位,对于64位系统是128位。

至少有三个可能的原因:

  • malloc需要产生适合所有原始类型的内存。 SSE指令的数据需要128位对齐。 (也可能有您的平台支持的其他128位基本类型,目前不会出现在我这里)。

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

  • 它可能正在分配保护字节以便检测缓冲区溢出等等。

malloc保证返回的内存适合任何基本类型。 此外,内存块可以填充一些警卫字节来检查内存损坏,这取决于设置。

如果你想分配连续的地址,你应该在同一个malloc上分配它们

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