c++ - float 组是否总是与 16 字节边界对齐?

标签 c++ c memory-management

我的理解是,如果您希望数组对齐,则必须明确指定数组的对齐方式。

但是,我声明的 float 组似乎总是对齐到 16 字节。

float *ptr1 = new float[1];
cout<<"ptr1: "<<ptr1<<endl;
float *ptr2 = new float[3];
cout<<"ptr2: "<<ptr2<<endl;
float arr1[7];
cout<<"arr1: "<<arr1<<endl;
float arr2[9] __attribute__((aligned(2)));
cout<<"arr2: "<<arr2<<endl;

这是输出

ptr1: 0x13dc010
ptr2: 0x13dc030
arr1: 0x7fff874885c0
arr2: 0x7fff87488590

这是有原因的吗?我正在使用 gcc 4.6.3

但是,如果它是一个指向浮点位置的指针或静态分配的,我看不到它

static float arr3[9] __attribute__((aligned(2)));
cout<<"arr3: "<<arr3<<endl;
float *x;
cout<<"x: "<<x<<endl;

输出:

arr3: 0x4030b2
x: 0x7fff8c7dd9e8

此代码在 x64 上运行。

最佳答案

对齐要求由每个编译器决定,受硬件要求和任何相关的影响ABI .

C 和 C++ 语言讨论了类型的对齐方式,但它们没有强加任何特定要求(除了,例如,结构的对齐方式至少是其任何成员的对齐方式)。一个有效的实现可以允许所有数据类型按字节对齐,或者它可以要求每个标量类型按其自身的大小对齐(后者更常见)。中间对齐是可能的,例如在 4 字节边界上对齐 8 字节类型。

特别是在 x86 上,将标量与其大小对齐可以提高访问效率,但未对齐的访问仍然可以正常工作,只是速度稍慢一些。

float 数组的要求 对齐方式与单个float 对象的要求对齐方式相同。如果 float 是 4 个字节,那么对齐不能超过 4 个字节,因为数组在它们的元素之间没有间隙。

如您(可能)所见,特定的编译器可能会选择对数组对象施加更严格的对齐方式,如果它能使访问这些对象的效率更高一些的话​​。

如果 new 运算符是通过调用 malloc 实现的,那么所有 new 分配的对象都将具有对任何类型都足够严格的对齐方式.

如果 float 数组始终与 16 字节边界对齐,那是因为您的编译器选择以这种方式分配它们,而不是因为语言要求这样做。另一方面,如果您使用别名将 float 数组强制为 4 字节对齐(假设 sizeof (float) == 4),则访问该数组及其元素仍应正常工作。

顺便说一句,当我在我的 x86_64 系统上运行您的代码(将其包装在 main 程序中之后)时,我得到的结果与您的类似。当我在 x86 系统上运行它时,我得到:

ptr1: 0x9e34008
ptr2: 0x9e34018
arr1: 0xbfefa160
arr2: 0xbfefa17c

我在两个系统上都在 Linux 下使用 gcc。

所以对您的问题的直接回答是否定的,float 数组并不总是与 16 字节边界对齐。

但在大多数情况下,您没有特别需要关心的理由。除非您使用别名技巧(将某个已声明类型的对象视为另一种类型),否则编译器总是至少为每个对象提供正确访问所需的对齐方式。

关于c++ - float 组是否总是与 16 字节边界对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20101406/

相关文章:

c++ - Windows XP 的版本帮助函数

c - <string.h> 和 <strings.h> 的区别

c++ - 指向无效内存时 sizeof(*ptr) 的行为是否未定义?

ios - UIImage已发布但CGImage未发布

ios - 具有可选 IBOutlet 的属性多态性

c++ - qt 渲染图表不更新标题/图例

c++ - 静态注册会导致惨败吗

c++ - 从 C++ 中的函数重新调整多个 vector ?

Pthreads、MPI 和 OpenMP 中的 C++

iphone - iOS 允许应用使用多少内存?