我认为问题在于您的数组在堆栈上,并且您的编译器太旧而无法支持过度对齐的堆栈变量。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
这是预期的。使用您的原始代码,我只是像您一样获得随机值。