2011-08-27 20 views
7

जब मैं इस तरह के संघ के आकार को मुद्रित करता हूं:मेरे यूनियन का आकार मुझे अपेक्षा से बड़ा क्यों है?

union u { 
    char c[5]; 
    int i; 
} un; 

इसका उपयोग कर:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    printf("size of union = %d ",sizeof(un)); 
    return 0; 
} 

मुझे विजुअल सी ++ का उपयोग करके 8 का उत्तर मिलता है, लेकिन मुझे उम्मीद है 5. क्यों?

ठीक है, उसी उदाहरण के लिए, मैंने ऐसा कुछ किया:

int i1 = 0x98761234; 
un.i = i1; 
printf("\n un.c[0] = %x ",un.c[0]); 
printf("\n un.c[1] = %x ",un.c[1]); 
printf("\n un.c[2]= %x ",un.c[2]); 
printf("\n un.c[3] = %x ",un.c[3]); 
printf("\n un.c[4] = %x ",un.c[4]); 
printf("size of union = %d ",sizeof(un)); 

मुझे

un.c[0] = 34; 
un.c[1] = 12; 
un.c[2] = 76; 
un.c[3] = ffffff98; 

जैसे परिणाम मिल गए हैं un.c [3]

पर 6fs क्यों हैं

उत्तर

11

sizeof ऑपरेटर उस प्रकार ऐसा है कि सब कुछ अभी भी सही ढंग से संरेखित हो जाने की एक सरणी में किसी भी गद्दी अलग तत्वों के लिए आवश्यक सहित एक चर या प्रकार के आकार, उत्पादन करता है। चूंकि आपके संघ में int सदस्य है, इसलिए इसे 4-बाइट गठबंधन करने की आवश्यकता है, इसलिए इसका "प्राकृतिक" आकार 4 बाइट्स के अगले एकाधिक भाग तक ऊपर की ओर जाता है।


ffffff98 क्योंकि आप पर हस्ताक्षर किए char साथ संकलित कर रहे हैं है। %x का उपयोग ऐसे तर्क के साथ करें जो unsigned int नहीं है अपरिभाषित व्यवहार का कारण बनता है; जो आप देख रहे हैं उसे कभी-कभी साइन-एक्सटेंशन कहा जाता है। आपके एलियासिंग का परिणाम 0x98char के रूप में दोहराया गया है, जो -104 है। यह int करने के लिए प्रोत्साहित किया जा रहा पर अपने मूल्य को बरकरार रखे हुए है (यह डिफ़ॉल्ट तर्क प्रोन्नति कहा जाता है), और पूर्णांक -104 जब एलियास के रूप में unsigned int0xffffff98 हो जाता है।

1

संकलक मेमोरी एक्सेस को गति देने के लिए जहां भी वह structs, यूनियनों और कक्षाओं को चाहता है, पैडिंग जोड़ सकता है। आप इसका प्रभाव देख रहे हैं। विजुअल सी ++ के लिए, पैडिंग आमतौर पर सबसे बड़े सदस्य प्रकार के आकार का एक बहु होता है। इस उदाहरण में, सबसे बड़ा सदस्य एक int है, इसलिए यह कुल आकार 8 बनाने के लिए 3 अप्रयुक्त बाइट्स के साथ यूनियन को पैड करता है।

+0

मानते हुए 4 बाइट पूर्णांकों के लिए कुछ बाइट्स कहते हैं, सबसे बड़ा सदस्य सी, जो 5 बाइट्स है। संकलक पैडिंग जोड़कर इसे 8 तक बढ़ाता है। यदि सिस्टम 8-बाइट पूर्णांक का उपयोग कर रहा है, तो 8 का उपयोग यूनियन आकार के लिए किया जाता है। –

+0

@ ब्रायन मैंने कुछ जवाब स्पष्ट रूप से इंगित करने के लिए "सबसे बड़ा सदस्य प्रकार" पर टिप्पणी करने से पहले ही मेरा जवाब बदल दिया। –

+1

मुझे पता नहीं, मुझे अभी भी नहीं लगता कि आपका उत्तर स्पष्ट या सही है। आप कहते हैं कि सबसे बड़ा सदस्य एक int है, लेकिन यह नहीं है। यह 5 वर्णों की एक सरणी है। चूंकि 5> 4 यह मूल शब्द आकार के अगले एकाधिक तक चलता है, जो इसे बनाता है 8. –

3

आपके संघ का संरेखण इसके किसी भी सदस्य का सबसे बड़ा संरेखण होना चाहिए। यह 4 है। इसलिए, संघ का आकार उस आकार के साथ गठबंधन होना चाहिए। यह 5 हो सकता है (c संघ का सबसे बड़ा सदस्य है), लेकिन क्योंकि संघ का संरेखण 4 है, यूनियन का आकार 8 तक गद्देदार है।

ध्यान दें कि यह सिर्फ कुलपति ++। मानक को विशेष रूप से इसकी आवश्यकता नहीं होती है। हालांकि यह आवश्यकतानुसार पैड प्रकारों के कार्यान्वयन की अनुमति देता है, जो वीसी ++ करता है। जीसीसी कुछ अलग कर सकता है, और संकलन-समय स्विच हो सकते हैं जो आप इस व्यवहार को बदलने के लिए नियोजित कर सकते हैं।

0

आपके सुझावों के लिए धन्यवाद। मैंने कई उदाहरणों के साथ यह कोशिश की और देखा कि संघ का आकार (अधिकतम तत्व का आकार) + पैडिंग (उच्चतम डेटाटाइप के आकार के आधार पर) के बराबर है।

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