Ich glaube, das Problem ist, dass sich Ihr Array auf dem Stapel befindet und Ihr Compiler zu alt ist, um überausgerichtete Stapelvariablen zu unterstützen. GCC 4.6 und höher haben diesen Fehler behoben .
C11 / C ++ 11 Funktioniert alignas(64) float a[4];
nur für jede Zweierpotenzausrichtung.
So auch das GNU C, __attribute__((aligned(x)))
wie Sie es verwendet haben.
(In C11 #include <stdalign.h>
für #define alignas _Alignas
: cppref ).
Bei einer sehr großen Ausrichtung an einer 4-KB-Seitengrenze möchten Sie diese möglicherweise nicht auf dem Stapel haben.
Da der Stapelzeiger beim Starten der Funktion alles sein kann, gibt es keine Möglichkeit, das Array auszurichten, ohne viel mehr zuzuweisen, als Sie benötigen, und es anzupassen. (Compiler verwenden and rsp, -4096
oder äquivalent und verwenden keines der zugewiesenen 0 bis 4088 Bytes. Eine Verzweigung, ob dieser Speicherplatz groß genug ist oder nicht, wäre möglich, wird jedoch nicht durchgeführt, da große Ausrichtungen viel größer sind als die Größe des Arrays oder anderer lokaler Elemente sind nicht der Normalfall.)
Wenn Sie das Array aus der Funktion in eine globale Variable verschieben, sollte es funktionieren. Das andere, was Sie tun können, ist, es als lokale Variable beizubehalten (was eine sehr gute Sache ist), aber machen Sie es static
. Dadurch wird verhindert, dass es auf dem Stapel gespeichert wird. Beachten Sie, dass beide Methoden nicht thread- oder rekursionssicher sind, da nur eine Kopie des Arrays vorhanden ist.
Mit diesem Code:
#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]);
}
Ich verstehe das:
0x804c000 0x804c004 0x804c008 0x804c00c
Welches ist, was erwartet wird. Mit Ihrem Originalcode erhalte ich nur zufällige Werte wie Sie.