我相信问题在于您的数组在堆栈上,并且您的编译器太旧了,无法支持过度对齐的堆栈变量。GCC 4.6及更高版本修复了该错误。
C11 / C ++ 11alignas(64) float a[4];
只适用于2对齐的任何幂。您使用
GNU C时__attribute__((aligned(x)))
也是如此。
(在C11中,#include <stdalign.h>
对于#define alignas _Alignas
:cppref)。
但是,如果对齐范围非常大(到4k页面边界),则可能不希望将其放在堆栈上。
因为在函数启动时堆栈指针可以是任何东西,所以如果不分配过多的内存并进行调整,就无法对齐数组。(编译器将and rsp, -4096
等效或不使用分配的0到4088字节中的任何一个;可能会分支该空间是否足够大,但不会进行分支,因为巨大的对齐方式比数组或其他局部大小大得多不是正常情况。)
如果将数组移出函数并移至全局变量,则该数组应该起作用。您可以做的另一件事是将其保留为局部变量(这是非常好的事情),但要使其成为static
。这样可以防止将其存储在堆栈中。请注意,这两种方式都不是线程安全的或递归安全的,因为只有一个数组副本。
使用此代码:
#include <stdio.h>
float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
int
main(void)
{
printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}
我得到这个:
0x804c000 0x804c004 0x804c008 0x804c00c
这是预期的。使用您的原始代码,我将像您一样获得随机值。