Sorunun, dizinizin yığında olması ve derleyicinizin aşırı hizalanmış yığın değişkenlerini destekleyemeyecek kadar eski olması olduğuna inanıyorum. GCC 4.6 ve sonrası bu hatayı düzeltti .
C11 / C ++ 11 alignas(64) float a[4];
Herhangi bir 2 hizalamanın gücü için çalışır. Sizin kullandığınız
GNU C __attribute__((aligned(x)))
de öyle.
(In C11, #include <stdalign.h>
için #define alignas _Alignas
: cppref ).
Ancak 4k sayfa sınırına göre çok büyük bir hizalama durumunda, bunu yığında istemeyebilirsiniz.
Yığın işaretçisi, işlev başladığında herhangi bir şey olabileceğinden, ihtiyacınız olandan çok daha fazlasını ayırmadan ve onu ayarlamadan diziyi hizalamanın bir yolu yoktur. (Derleyiciler, and rsp, -4096
tahsis edilen 0 ila 4088 bayttan hiçbirini kullanmayacak veya eşdeğeri kullanmayacak; bu alanın yeterince büyük olup olmadığına göre dallanma mümkün olabilirdi, ancak yapılmaz çünkü büyük hizalamalar dizinin veya diğer yerellerin boyutundan çok daha büyüktür. normal durum değildir.)
Diziyi işlevin dışına ve global bir değişkene taşırsanız, çalışması gerekir. Yapabileceğiniz diğer şey, onu yerel bir değişken olarak tutmaktır (ki bu çok iyi bir şeydir), ama yapın static
. Bu, yığında depolanmasını önleyecektir. Dizinin yalnızca bir kopyası olacağından, bu iki yolun da iş parçacığı veya özyineleme güvenli olmadığına dikkat edin.
Bu kodla:
#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]);
}
Bunu anlıyorum:
0x804c000 0x804c004 0x804c008 0x804c00c
beklenen de bu. Orijinal kodunuzla, sizin yaptığınız gibi rastgele değerler alıyorum.