ฉันเชื่อว่าปัญหาคืออาร์เรย์ของคุณอยู่บนสแต็กและคอมไพเลอร์ของคุณเก่าเกินไปที่จะรองรับตัวแปรสแต็กแบบจัดแนวเกินไป GCC 4.6 และแก้ไขข้อบกพร่องนั้นในภายหลังได้รับการแก้ไขข้อผิดพลาดที่
C11 / C ++ 11 alignas(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
ซึ่งเป็นสิ่งที่คาดหวัง ด้วยรหัสเดิมของคุณฉันจะได้รับค่าแบบสุ่มเหมือนที่คุณทำ