2012-02-13 11 views
5

iOS एप्लिकेशन में, मैं एक struct है कि इससंरचना संरेखण से संबंधित EXC_BAD_ACCESS?

typedef struct _Pixel { 
    signed char r; 
    signed char g; 
    signed char b; 
} Pixel; 

मेरी कोड में की तरह लग रहा है, मैं calloc के साथ इन की एक सरणी का आवंटन:

Pixel* buff = calloc(width * height, sizeof(Pixel)); 

अब, यह सिम्युलेटर में पूरी तरह से काम करता है , लेकिन डिवाइस पर, यदि मैं buff[width * height - 1] (यानि buff में अंतिम तत्व) तक पहुंचने का प्रयास करता हूं, तो मुझे EXC_BAD_ACCESS मिलता है।

यह मेरे लिए कोई मतलब नहीं था, इसलिए डिबगिंग के कुछ ही घंटों के बाद, मैं अगर यह संरेखण मुद्दा किसी तरह का था सोचा है, तो एक लहर में मैंने कोशिश की:

typedef struct _Pixel { 
    signed char r; 
    signed char g; 
    signed char b; 
    signed char padding; 
} Pixel; 

के आकार बनाने पिक्सेल दो की शक्ति।

यह EXC_BAD_ACCESS को हल करता है, लेकिन यह बहुत अजीब है। क्या किसी को यहां क्या हो रहा है में कोई अंतर्दृष्टि है? क्या मैं सिर्फ संरचना को पैड करके अंतर्निहित समस्या का मुखौटा कर रहा हूं या संरेखण वास्तव में खराब पहुंच का कारण बन सकता है (मैंने सोचा था कि संरेखण केवल प्रदर्शन पर प्रभाव था, सहीता नहीं)।

+0

हे बिल दो चीजें। चूंकि SO मुझे एक चरित्र को संपादित करने नहीं देता है, इसलिए आपको कॉलोक में एक टाइपो मिला है। आप अंत में एक कोष्ठक याद कर रहे हैं। आपकी मुख्य समस्या के लिए, यदि आप या तो कहीं और बफ को फिर से चालू करते हैं, क्या आप पिछले तत्व तक पहुंचने से पहले * buff * पर कुछ और करते हैं? – Lefteris

+0

चौड़ाई और ऊंचाई के अपने मूल्यों की फिर से जांच करें ... !!! –

+0

यह कोड है जो महीनों के लिए काम करता है - केवल अंतर यह है कि मैंने सीजीएफएलएटी से हस्ताक्षरित बाइट्स तक स्ट्रक्चर सदस्यों के प्रकार को बदल दिया। तो चौड़ाई और ऊंचाई समस्या नहीं है - यह संरचना के लेआउट के साथ कुछ करने के लिए है। – Bill

उत्तर

3

EXC_BAD_ACCESS is related to alignment. x86 के विपरीत, एआरएम को कुछ सीमा तक गठबंधन स्मृति पहुंच की आवश्यकता होती है।

संरेखण को नियंत्रित करने के लिए, #pragma push, #pragma pack(n) और #pragma pop का उपयोग करें।

http://tedlogan.com/techblog2.html

+2

उसने संरेखण को नियंत्रित करने के लिए नहीं पूछा था। उन्होंने पूछा कि क्या कोई जानता है कि क्यों पैडिंग के बिना यह पहले स्थान पर EXC_BAD_ACCESS का कारण बनता है – Lefteris

+0

गलत-संरेखण एआरएम पर EXC_BAD_ACCESS का कारण है। अनुमोदित के लिए x86 पर व्यवहार न करें। – ZhangChn

+0

यह अजीब बात है, क्योंकि वह बाइट्स तक पहुंच रहा है, जो संरेखण अपवादों से ग्रस्त नहीं होना चाहिए। हो सकता है कि संरचना उस आवेदन के एक हिस्से में पारित हो जाए जो संरचना परिवर्तन के बाद पुन: संकलित नहीं किया गया था? –

2

देखें यह संरेखण की समस्या है। न्यूनतम संरचना संरेखण आकार 4 बाइट्स है और यह संरचना में डेटाटाइप घोषणा (उदाहरण के लिए डबल) के अनुसार अलग-अलग होगा। अगर आप एकल ब्लॉक के आकार को प्रिंट करते हैं, तो यह 4 के बजाय 3 प्रिंट करेगा। लेकिन यदि आप आकार का प्रिंट करते हैं आपकी संरचना, यह न्यूनतम संरेखण आकार की वजह से 4 प्रिंट करेगा।

मान लें कि क्या आपके पास संरचना में 'int' तत्व भी है, तो एकल ब्लॉक और संरचना दोनों का आकार 8 होगा। यह संकलक के कारण वर्णों और int के बीच पैडिंग बाइट आवंटित करने के लिए मजबूर है। उदाहरण

typedef struct { 

signed char r; 
signed char g; 
signed char b; 
}MyType; 

MyType *type = (MyType *)calloc(20, sizeof(MyType)); 
printf("size: %ld", sizeof(MyType)); 
printf("size: %ld", sizeof(type[0])); 

के लिए पहले printf बयान 4 प्रिंट होगा और दूसरा 3. प्रिंट होगा क्योंकि डिफ़ॉल्ट संरचना संरेखण आकार 4 बाइट्स और वास्तविक आवंटन 3 बाइट है। अब एक ही संरचना में एक int प्रकार जोड़ें।

typedef struct { 

signed char r; 
signed char g; 
signed char b; 

int i;   // New int element added here 
}MyType; 

MyType *type = (MyType *)calloc(20, sizeof(MyType)); 
printf("size: %ld", sizeof(MyType)); 
printf("size: %ld", sizeof(type[0])); 

यहाँ दोनों printf बयान 8. प्रिंट क्योंकि संकलक चार और पूर्णांक के बीच में एक बाइट आवंटित करने के लिए सिर्फ चार के गुणकों में संरेखण रखने के लिए मजबूर होगा। फिर संरचना के रूप में नीचे दिए गए की तरह दिखाई देगा,

typedef struct { 

signed char r; 
signed char g; 
signed char b; 

char padding; // Padding byte allocated to keep alignment. 

int i; 
}MyType; 

तो आप अपने संरचना में एक गद्दी बाइट जोड़ने के लिए वास्तविक आवंटन की वजह से संरेखण रखने के लिए 3 बाइट है।

संरचना आवंटन आकार संरचना के अंदर विभिन्न डेटाटाइप घोषणाओं की स्थिति के अनुसार भी अलग-अलग होगा।

संबंधित मुद्दे