我按如下方式动态分配内存:
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。
答案 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
保证返回的内存与任何基本类型正确对齐。此外,可以使用一些保护字节填充内存块以检查内存损坏,这取决于设置。