4

malloc() documentation says that the returned pointer is suitably aligned for any kind of variable. On my system, a long double has size 12, however some pointers returned by malloc() are aligned on 8 byte boundary and not 12. (ptr % 12 gives 4). Can anybody point out what am I missing here? Thanks in advance.

4

5 回答 5

5

显然,long double不需要对齐到 12 个字节。在像你这样的系统上,原始 C 类型的最大对齐是 8 个字节double。不要混淆对齐和大小 - 虽然许多较小(尤其是原始)类型必须自然对齐 - 即与它们自己的大小对齐 - 这对于较大的数据类型(考虑碎片)是禁止的,并且不会使任何事情变得更容易硬件。

于 2013-06-29T13:31:25.713 回答
4

On gcc for Linux and x86 you have:

sizeof (long double) == 12

and

on gcc for Linux and x64 you have:

sizeof (long double) == 16

The ABI alignment requirements for x64 long double is 16-bytes. For x86, no type requires more than 8-bytes of alignment.

To respect that glibc malloc returns memory object aligned with 8-bytes on 32-bit system and aligned on 16-bytes for 64-bit systems.

From glibc doc:

The block that malloc gives you is guaranteed to be aligned so that it can hold any type of data. On GNU systems, the address is always a multiple of eight on most systems, and a multiple of 16 on 64-bit systems.

于 2013-06-29T13:52:01.983 回答
3

在任何合理的 cpu 架构上,大小为 12 的对象的最大可能对齐要求是 4。对齐要求必须是 2 的幂,将类型的大小均分。实际上,这会导致非常差的对齐(对象跨越缓存行甚至页面!),这就是 x86_64 ABI 将大小更改long double为 16: 的原因,以便可以对齐它而不跨越任何边界。

于 2013-06-29T15:20:40.440 回答
0

malloc will return memory properly aligned for any type, because typically the pointer it returns is converted to a pointer of an arbitrary type and such conversion is typically (read: infinitely close to 100% of the time) a no-op. For any architecture and compiler the maximum alignment of any type is however a constant and typically it is the maximum of the alignment of all primitive types. The size of an object should however be a multiple of its alignment. Sometimes this requirement must be met by adding padding to the value inside the object.

If your compiler is modern enough it will support _Alignof, similar to sizeof, so you can check the actual alignment with a small program. I think on your architecture the maximum alignment is 4. If malloc always returns addresses aligned by 8, then it still complies. It is not unusual for malloc to meet an alignment that is a multiple of the maximum alignment of the types.

于 2013-06-29T13:54:14.300 回答
0

您错过了虽然类型的大小必须是其对齐方式的倍数(受实际硬件限制),但它们不必相等。

在 的情况下long double,这转化为

_Alignof (long double) == 4
sizeof (long double) == 12

使用 gcc/x86 和

_Alignof (long double) == 16
sizeof (long double) == 16

使用 gcc/x64,在这两种情况下long double都具有 80 位扩展精度。

如果我们不受对齐的限制,我们很自然会得到

sizeof (long double) == 10

在存在对齐的情况下,我们要么必须使用 2 对齐(出于效率原因我们不这样做),要么向数组引入填充以使元素正确对齐。这违反了 C 语言语义,因为数组的大小是其元素大小和计数的乘积。

于 2013-06-29T15:07:50.350 回答