【问题标题】:why malloc always return a address of 0x???????8为什么 malloc 总是返回 0x 的地址???????8
【发布时间】:2012-02-27 18:22:54
【问题描述】:

我写了一个简单的代码:-

 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。
  • 你为什么在malloc之前free(aa)?另外,sizeof(char) 总是返回 1 个字节。
  • 抱歉重复了两行代码

标签: c malloc heap-memory


【解决方案1】:

原因一般根源于alignment问题;约束是为了满足处理器要求、协助cache optimization strategies 或其他原因。

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

但是,您可能会根据经验发现它们的对齐程度甚至比上述约束严格要求的程度更高。例如,特定的分配器实现可能会出于以下原因增加它:

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

【讨论】:

  • 实际上C 要求返回的指针适合任何类型的对齐。在需要 8 字节对齐的类型的系统上,指针的最后一个半字节必须是 0 或 8。
  • @R.. 我指的是这样一个事实,无论 C、C++ 还是环境实际需要它,分配器都可能出于它自己看到的任何原因选择增加块大小也适合(例如,为了减少碎片,允许指针减少 4 位,并使这 4 位可以用作标志)。收紧语言以包含此内容。
  • @R.. 我现在看到 at-aix 更清楚地表达了这一点。你必须相信我的话,当这个答案第一次出现时,我已经意识到这一点并试图表达这一点!
  • 抱歉,我认为我的评论太挑剔了。我没有投反对票或其他任何事情;我只是觉得不清楚malloc 必须做一些对齐来满足要求,除了可选的额外对齐来满足它自己的实现需求或性能目标。
  • @R.. Grando。我个人也很喜欢 at-aix 的答案,因此我对此 +1 - 它确实准确而简洁地回答了它(与我为什么分配器可能出于自身原因选择增加对齐的坏例子相反)。 (这是另一条评论中的“唯一正确”位让我生气并打字:D)
【解决方案2】:

有几个问题在起作用:

  1. malloc() 需要返回一个对齐的地址,以便它可以用于任何数据类型。更正式的(C99 7.20.3):

    如果分配成功,则返回的指针经过适当对齐,以便可以将其分配给指向任何类型对象的指针,然后用于访问分配的空间中的此类对象或此类对象的数组(直到空间被显式释放)。

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

【讨论】:

    【解决方案3】:

    原因是对齐,8字节对齐被认为是最有效的。

    您可以从这里开始:http://www.delorie.com/gnu/docs/glibc/libc_31.html

    【讨论】:

      猜你喜欢
      • 2021-08-29
      • 2017-07-30
      • 2019-10-08
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2017-10-08
      • 2018-10-01
      相关资源
      最近更新 更多