2

我正在阅读有关 malloc 实现的演示文稿,在幻灯片 7 上,它建议将区域大小和可用性存储在一个单词中以节省空间。另一种方法是使用两个字,这很浪费,因为可用性位只需为 0 或 1。

这是给定的解释:

  • 如果块对齐,低位地址位始终为 0
  • 为什么要存储始终为 0 的位?
  • 将其用作已分配/空闲标志!读取大小字时,必须屏蔽掉该位

http://courses.engr.illinois.edu/cs241/sp2012/lectures/09-malloc.pdf

但我并不真正理解它是如何工作的以及如何在 C 中实现它。为什么大小整数的一位总是 0?

4

3 回答 3

3
  • 如果块对齐,低位地址位始终为 0

这是了解它发生了什么的关键。许多 CPU 要求将多字节基元值存储在可被基元字节数整除的地址:16 位基元需要存储在偶数地址;32 位int的 s 需要存储在可被 4 整除的地址,以此类推。尝试int通过对应于奇数地址的指针访问 会导致总线错误。

在这样的系统中,malloc必须始终返回适合存储给定 CPU 支持的任何原语的地址。因此,如果 CPU 支持 32 位整数,则返回的所有地址malloc必须能被 整除4。这样的地址被称为是对齐的。为了遵守,malloc实现将程序请求的块大小在末尾填充 0 到 3 个字节,使其长度可被4. 作为该决定的结果,对齐块的地址的最后两位将始终为零。的实现malloc可以将这些位用于自己的目的,只要在将结果返回给调用者之前将它们“屏蔽”即可。

于 2012-11-01T11:53:35.947 回答
1

Why is one bit of the size integer always 0?

我明白为什么这令人困惑,但我不认为这就是他们在幻灯片 7 上所说的。他们说低位地址位始终为 0。

对象的内存地址与特定边界对齐,这意味着对象与其大小的倍数对齐。

所以一个 64 位整数与八字节边界对齐;0x7fff315470d8

如果指针始终与八字节边界对齐,则低三位始终为零。即:0x8 16 = 1000 2

基本上,只要在取消引用指针之前将它们取出,您就可以在那些低位中粘贴您想要的任何内容。在 64 位的情况下,您有 3 个始终为 0 的位,因此您可以存储 3 个“标志”。在这个电源点的情况下,他们说拿最低位并将其用于“已分配”标志。只要分配了内存,就在其中粘贴一个 1,当您将指针发送给用户时将其屏蔽掉。

于 2012-11-01T12:11:05.863 回答
1

malloc(3)(由 Posix 指定)应该

  • 返回一个新的内存块;或NULL失败;返回的指针不是程序中任何其他指针的别名
  • 返回一个适当对齐的内存块。对齐约束是编译器、ABI 和处理器特定的。(通常,对齐应该是两个词)。

大小并不总是零。(实际上,它永远不会为零)。您可以将其四舍五入为两个字的倍数,并将最后一位用作已用/空闲位。

然而,返回的指针malloc应该适当地对齐,例如到 8 个字节。因此它们的底部 3 位为零,并且 -ed 区域的分配大小(以字节为单位)malloc是 8 字节的倍数(高于传递给的请求大小malloc),因此最后 3 位为零(您可以使用最后一位其他用途,例如使用/空闲位)。

于 2012-11-01T11:47:53.720 回答