4

我动态分配内存如下:

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

4 回答 4

7

glibcmalloc对于小于 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)
...
*/

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

于 2013-01-31T00:16:34.713 回答
4

至少三个可能的原因:

  • malloc需要为所有原始类型生成适当对齐的内存。 SSE 指令的数据需要 128 位对齐。(目前我还没有想到您的平台支持的其他 128 位原始类型。)

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

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

于 2013-01-31T00:02:36.727 回答
0

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

char *heap_start1, *heap_start2;
heap_start1 = (char*) malloc(2 * sizeof(char));
heap_start2 = heap_start1 + 1;
于 2013-01-31T00:04:54.590 回答
0

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

于 2013-01-31T00:13:49.487 回答