2011-12-15 12 views
7

यहाँ प्रश्न में कोड हैसी सूचक अंकगणित sizeof (struct)

#include <stdio.h> 

struct test { 
    unsigned char t; 
    unsigned short u; 
    unsigned char v; 
}; 


int main() 
{ 
    struct test * a = (void *) 0x1000; 

    printf("%x %p %p\n", 
      sizeof(struct test), 
      a + sizeof(struct test), 
      a - sizeof(struct test)); 

    return 0; 
} 

sizeof (struct परीक्षण) 6 प्रिंट, तो मैं उम्मीद करेंगे देखने के लिए:

6 0xffa 0x1006

इसके बजाय मुझे

6 0x1024 0xfdc 

पिछली बार मैं सी हेक्ड, 0x24, या 36, 6 के बराबर नहीं था। यह किसी भी चीज़ से गठबंधन नहीं है जिसे मैं बता सकता हूं। मैं पूरी तरह से नुकसान में हूँ।

क्या कोई मुझे बता सकता है कि मुझे ये मूल्य क्यों मिल रहे हैं?

उत्तर

16

समस्या यह है कि जब आप पॉइंटर अंकगणित करते हैं, तो यह डेटाटाइप के आकार के एकाधिक द्वारा बढ़ता है।

तो आप प्रभावी ढंग से क्या कर रहे हैं sizeof(struct test) के वर्ग द्वारा जोड़ रहा है।

sizeof(struct test) = 6 के बाद से, आप 6 * 6 = 36 द्वारा पते को बढ़ा रहे हैं। इसलिए 0x1006 और 0xffa के बजाय आपको 0x1024 और 0xfdc क्यों मिलता है। (आप भी + और - प्रयोग किया, लेकिन है कि एक छोटी सी बात है।)

इसके बजाय, सिर्फ इस कार्य करें:

printf("%x %p %p\n", 
     sizeof(struct test), 
     a + 1, 
     a - 1); 
1

आपके पास एक टाइप किया गया पॉइंटर है।

तो जब आप इसे बढ़ाते हैं तो मेरा 1 (यानी a + 1) इसका अर्थ है a + sizeof(type)

तो a + sizeof(type) = a + sizeof(type) * sizeof(type) = a + 6 * 6 (sizeof (परीक्षण के रूप में अपने मामले) = में 6)

है यही कारण है कि तुम कहाँ से 0x24 या 36 हो रही है।

2

मुझे लगता है कि आप a + 1 और a - 1 के लिए देख रहे हैं।

(a + x) वही है &a[x]

+2

आप शायद यह कहना चाहते हैं कि '* (ए + एक्स)' 'x [x]' या '(a + x)' जैसा ही है 'और एक [x] 'जैसा ही है। –

4

जब आप इस तरह पॉइंटर अंकगणित करते हैं, तो आप तत्वों की संख्या से आगे या पीछे जाते हैं, भले ही वह चर एक सरणी में था। तो आप वास्तव में केवल a + 1 और a - 1 का उपयोग करना चाहते हैं, जो हर बार 6 बाइट्स से आगे बढ़ना चाहिए।

महत्वपूर्ण: ध्यान रखें कि संकलक संरेखण में सहायता के लिए आपकी संरचना में पैडिंग जोड़ सकता है। केवल यह न मानें कि आपके पास दो वन-बाइट वर्ण हैं और दो-बाइट कम है कि आपकी संरचना आकार में 4 बाइट होगी --- यह मामला यहां नहीं है। (वास्तव में, यह न मानें कि आप चार या छोटे आकार के आकार को जानते हैं; मैंने पहले 2-बाइट वर्ण देखा है)।

+3

असल में यह बिल्कुल सटीक नहीं है।यह सरणी तत्वों के बीच में पैडिंग जोड़ नहीं सकता है। यह संरचना के तत्वों के बीच और संरचना के अंतिम तत्व के बीच पैड क्या कर सकता है (यह शायद आप जिस बिट का जिक्र कर रहे हैं)। लेकिन अगर संरचना संरेखण की आवश्यकता है तो संरचना स्वयं को सही आकार के रूप में गद्देदार है - यहां छह बाइट्स शायद 'चार (1), पैड (1), लघु (2), चार (1), पैड (1) 'लेकिन कि अंतिम पैडिंग एक एकल संरचना तत्व से संबंधित है, यह उस संरचना से बने सरणी में _between_ तत्व नहीं है। नाइटपिक मोड बंद :-) – paxdiablo

+1

धन्यवाद, मैंने सी 99 स्पेक पर वापस देखने के बाद मेरी प्रतिक्रिया दोबारा शुरू की है। –

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