为什么malloc总是返回0x???????8地址?

3
我写了一个简单的代码:-
 void * aa = malloc(10 * sizeof(char));
 printf("%X\n", aa);
 free(aa);

它总是打印 ???????8, 我想问的是: malloc是否总是返回4 * n地址? 为什么这里地址的最后一个数字总是8?为什么不是4或C? 我的环境: ubuntu 10.04(32位) gcc版本4.4.3


printf应该是printf("%p\n", aa);。而且sizeof(char)的定义是1。 - cnicutar
为什么在 malloc 之前要执行 free(aa)?此外,sizeof(char) 总是返回 1 字节。 - Taco de Wolff
抱歉,代码中有两行重复的内容。 - MouJian
3个回答

8

这些原因通常源于对齐问题;约束条件存在是为了满足处理器要求,协助缓存优化策略或其他原因。

作为核心目的的一部分,满足系统(操作系统、语言规范、处理器)对齐要求,否则将在运行时导致故障(根据系统影响大小不同)或低效行为(需要进行额外的内存读取才能获取与其跨越内存块边界相同的数据),会应用最小对齐要求。

然而,您可能会发现它们实际上比前面的约束条件所要求的对齐程度更高。例如,特定的分配器实现可能会出于以下原因增加对齐:

  • 添加内存溢出屏障和/或其他完整性检查/验证机制
  • 允许更有效地存储指针(例如,如果您知道底部4位为零,则可以在持久化它们时以某种方式将它们打包)
  • 简化或增加地址计算的效率
  • 减少碎片化和/或其他原因,这些原因可能似乎对个别分配不提供任何好处,但满足更大一组分配的某些目标

实际上,C语言要求返回的指针对于任何类型都要适当地对齐。在需要8字节对齐的类型存在的系统中,指针的最后一个半字节必须是0或8。 - R.. GitHub STOP HELPING ICE
@R.. 我指的是,无论C、C++还是环境是否真正需要,分配器都可以选择自己合适的原因来增加块大小(例如,为了减少碎片化,使指针减少4位并使这些4位可以用作标志)。收紧语言以包括此内容。 - Ruben Bartelink
@R.. 我现在明白了,at-aix 更清晰地表达了那个观点。当我第一次回答时,你只能相信我已经意识到了这一点,并试图传达这一点! - Ruben Bartelink
抱歉,我觉得我的评论过于批判了。我没有投反对票或做任何事情;我只是认为不清楚的是,malloc必须进行一些对齐以满足要求,除了可选的额外对齐以满足其自身的实现需求或性能目标。 - R.. GitHub STOP HELPING ICE
@R.. Grando。我个人也喜欢at-aix的答案,因此我给它+1——它确实精准而简洁地回答了问题(与我举的一些糟糕示例相反,这些示例说明分配器可能出于自己的原因选择增加对齐方式)。 (是另一个评论中“唯一正确”的部分让我激动并开始打字:D) - Ruben Bartelink
我在那个回答中使用的 / 是因为我不确定是应该说“最正确”的答案还是“唯一正确”的答案。 :-) - R.. GitHub STOP HELPING ICE

6
有几个问题需要考虑:
  1. malloc()被要求返回一个地址,使它可以用于任何数据类型。更正式地说(C99 7.20.3):

    如果分配成功,返回的指针将适当对齐,以便将其分配给任何对象的指针,然后用于访问所分配的空间中的该对象或该对象的数组(直到空间明确地被释放)。

  2. 内存分配器的实现者可以选择使用大于对齐要求所暗示的最小块的内存块。例如,出于效率的原因可以这样做(涉及到权衡)。


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接