मेरा मानना है कि समस्या यह है कि आपका सरणी स्टैक पर है, और यह कि आपका कंपाइलर स्टैक वेरिएबल को ओवर-अलाइंड करने में पुराना है। जीसीसी 4.6 और बाद में उस बग को ठीक कर दिया ।
C11 / C ++ 11 alignas(64) float a[4];
बस 2 संरेखण की किसी भी शक्ति के लिए काम करता है।
तो क्या जीएनयू सी __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
जो अपेक्षित है। आपके मूल कोड के साथ, मुझे आपके जैसे ही यादृच्छिक मूल्य मिलते हैं।