我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;