如何在 C 中分配 32 字节对齐的内存

Posted

技术标签:

【中文标题】如何在 C 中分配 32 字节对齐的内存【英文标题】:How to allocate a 32-byte aligned memory in C 【发布时间】:2012-07-30 03:08:52 【问题描述】:

在一个采访样本中遇到了这个问题。 How to allocate aligned memory only using the standard library? 中已经回答了一个 16 字节对齐的分配

但是,我有一个关于用于将最后 4 位归零的掩码的具体问题。此掩码“~0F”已用于使结果地址可被 16 整除。应该如何实现 32 字节对齐/可除性?

【问题讨论】:

您是否阅读了链接中的详细答案?那里有足够多的信息供您找出答案。如果你没有得到它,你应该学习它直到你得到它,因为否则这里给出的任何答案都不会提高你的技能。 事实上,那里有一个通用的实现,void test_mask(size_t align),它适用于任意 2 的幂对齐,包括 32。 顺便说一句,你的意思是 16 字节和 32 字节,而不是 16 位和 32 位。 感谢指正,将编辑标题 【参考方案1】:

首先,您提到的问题是 16 字节对齐,而不是 16 位对齐。

关于您的实际问题,您只想屏蔽 5 位而不是 4 位,以使结果与 32 字节对齐。所以应该是~0x1F

澄清一下:

要将指针对齐到 32 字节边界,您希望地址的最后 5 位为 0。(由于 100000 在二进制中是 32,因此 32 的任何倍数都将以 00000 结尾。)

0x1F 是二进制的 11111。由于它是一个指针,它实际上是一些 0 后跟 11111 - 例如,对于 64 位指针,它将是 59 个 0 和 5 个 1。 ~ 表示这些值是反转的 - 所以 ~0x1F 是 59 个 1,后跟 5 个 0。

当您使用ptr & ~0x1F 时,按位 & 会导致所有与 1 进行 &'ed 的位保持不变,并将所有与 0 进行 &'ed 的位设置为 0。所以你最终得到ptr 的原始值,除了最后 5 位已设置为 0。这意味着我们在 0 和 31 之间减去了一些数字,以便使 ptr 成为 32 的倍数,这就是目标。

【讨论】:

它是 ~0xF 和 ~0x1F 。而这并不能回答问题...查看链接,您会发现需要做的不仅仅是更换面具。 @JimBalter.. 我知道要获得 32 字节对齐的地址还需要做更多工作,我只是对掩码有疑问。 @happydave,感谢您对掩码的回答,但我仍然不确定这 5 位如何确保与 32 的可分性。我是位语义的新手,所以请不要无知 :) @DeepanjanMazumdar 如果将十进制数的最后 5 位替换为零,结果将是 100000 的倍数,对吗?使用 ~0x1F 屏蔽会清除低 5 位,因此结果是 32 = 2**5 = 100000(二进制)的倍数。编辑:我看到happydave 在他的最新编辑中包含了一个解释...... +1。 happydave 和 jim.. 谢谢你的解释.. 清除等于减法让我忽略了。

以上是关于如何在 C 中分配 32 字节对齐的内存的主要内容,如果未能解决你的问题,请参考以下文章

C语言字节对齐

如何检查内存地址在 C 中是不是为 32 位对齐

如何在 Objective C 中对齐内存?

为 SIMD 分配内存对齐的缓冲区; |16 如何给出 16 的奇数倍数,为啥要这样做?

内存对齐

JAVA里String数组在内存分配中分配的空间每个占几个字节?