खोज…


परिचय

डिफ़ॉल्ट रूप से, सी कंपाइलर संरचनाएं तैयार करते हैं, ताकि प्रत्येक सदस्य को 'अनलगनेटेड एक्सेस' के लिए दंड के बिना, डीआईएस अल्फा जैसी आरआईएससी मशीनों के साथ एक समस्या और कुछ एआरएम सीपीयू के लिए तेजी से एक्सेस किया जा सके।

सीपीयू वास्तुकला और संकलक के आधार पर, एक संरचना अपने घटक सदस्यों के आकार के योग की तुलना में स्मृति में अधिक जगह घेर सकती है। संकलक सदस्यों के बीच या संरचना के अंत में पैडिंग जोड़ सकता है, लेकिन शुरुआत में नहीं।

पैकिंग डिफ़ॉल्ट पैडिंग को ओवरराइड करती है।

टिप्पणियों

एरिक रेमंड के पास द लॉस्ट आर्ट ऑफ़ सी स्ट्रक्चर पैकिंग पर एक लेख है जो उपयोगी रीडिंग है।

पैकिंग संरचनाएं

सी में डिफ़ॉल्ट संरचनाएं गद्देदार हैं। यदि आप इस व्यवहार से बचना चाहते हैं, तो आपको इसे स्पष्ट रूप से अनुरोध करना होगा। GCC के तहत यह __attribute__((__packed__)) । 64-बिट मशीन पर इस उदाहरण पर विचार करें:

struct foo {
    char *p;  /* 8 bytes */
    char c;   /* 1 byte  */
    long x;   /* 8 bytes */
};

संरचना स्वचालित रूप से 8-byte संरेखण के लिए गद्देदार होगी और इस तरह दिखाई देगी:

struct foo {
    char *p;     /* 8 bytes */
    char c;      /* 1 byte  */

    char pad[7]; /* 7 bytes added by compiler */

    long x;      /* 8 bytes */
};

तो sizeof(struct foo) हमें 17 बजाय 24 देगा। ऐसा तब हुआ जब प्रत्येक चरण में 8 बाइट्स शब्द में 64 बिट कंपाइलर को पढ़ने / लिखने से लेकर मेमोरी में लिखने तक और जब char c; लिखने की कोशिश की जाती है, तो स्पष्ट होता है char c; स्मृति में एक बाइट एक पूर्ण 8 बाइट्स (यानी शब्द) प्राप्त की और पहले बाइट का केवल उपभोग करती है और इसकी बाइट्स की सात लगातार खाली रहती है और संरचना पैडिंग के लिए किसी भी पढ़ने और लिखने के संचालन के लिए सुलभ नहीं है।

संरचना पैकिंग

लेकिन यदि आप विशेषता packed जोड़ते हैं, तो संकलक गद्दी नहीं जोड़ेगा:

struct __attribute__((__packed__)) foo {
    char *p;  /* 8 bytes */
    char c;   /* 1 byte  */
    long x;   /* 8 bytes */
};

अब sizeof(struct foo) 17 को वापस आएगा।

आम तौर पर पैक्ड संरचनाओं का उपयोग किया जाता है:

  • अंतरिक्ष को बचाने के लिए।
  • नेटवर्क के प्रत्येक नोड के आर्किटेक्चर संरेखण के आधार पर नेटवर्क पर संचारित करने के लिए डेटा संरचना को प्रारूपित करना।

यह ध्यान में रखा जाना चाहिए कि कुछ प्रोसेसर जैसे कि एआरएम कॉर्टेक्स-एम 0 अनलगिनर्ड मेमोरी एक्सेस की अनुमति नहीं देते हैं; ऐसे मामलों में, संरचना पैकिंग से अपरिभाषित व्यवहार हो सकता है और सीपीयू दुर्घटनाग्रस्त हो सकता है।

संरचना पैडिंग

मान लीजिए कि यह struct 32 बिट संकलक के साथ परिभाषित और संकलित है:

struct test_32 {
    int a;      // 4 byte
    short b;    // 2 byte
    int c;      // 4 byte    
} str_32;

हम उम्मीद कर सकते हैं कि यह struct केवल 10 बाइट्स मेमोरी पर कब्जा कर सकती है, लेकिन sizeof(str_32) को प्रिंट करके हम देखते हैं कि यह 12 बाइट्स का उपयोग करता है।

ऐसा इसलिए हुआ क्योंकि कंपाइलर तेज पहुंच के लिए वैरिएबल को संरेखित करता है। एक सामान्य पैटर्न यह है कि जब आधार प्रकार एन बाइट्स पर कब्जा कर लेता है (जहां एन 2 की शक्ति है जैसे कि 1, 2, 4, 8, 16 - और शायद ही कभी कोई बड़ा), चर को एन-बाइट सीमा पर गठबंधन किया जाना चाहिए ( एन बाइट्स की एक बहु)।

sizeof(int) == 4 और sizeof(short) == 2 साथ दिखाए गए ढांचे के लिए, एक सामान्य लेआउट है:

  • int a; ऑफसेट 0 पर संग्रहीत; आकार 4।
  • short b; ऑफसेट 4 पर संग्रहीत; आकार 2।
  • अनाम 6 ऑफसेट पर पैडिंग; आकार 2।
  • int c; ऑफसेट 8 पर संग्रहीत; आकार 4।

इस प्रकार struct test_32 में 12 बाइट्स की मेमोरी होती है। इस उदाहरण में, कोई अनुगामी गद्दी नहीं है।

कंपाइलर यह सुनिश्चित करेगा कि किसी भी struct test_32 चर को 4-बाइट सीमा पर शुरू किया गया है, ताकि संरचना के सदस्यों को तेजी से पहुंच के लिए ठीक से गठबंधन किया जा सके। जैसे स्मृति आवंटन कार्यों malloc() , calloc() और realloc() सुनिश्चित करना है कि सूचक लौटे पर्याप्त रूप में अच्छी तरह से, किसी भी डेटा प्रकार के साथ उपयोग के लिए गठबंधन किया है, ताकि गतिशील आवंटित संरचनाओं ठीक से भी गठबंधन किया जाएगा आवश्यक हैं।

आप 64-बिट Intel x86_64 प्रोसेसर (जैसे Intel Core i7 - Mac पर चलने वाला MacOS सिएरा या Mac OS X) जैसी विषम परिस्थितियों को समाप्त कर सकते हैं, जहां 32-बिट मोड में संकलन करते समय, कंपाइलर double ए पर संरेखित होते हैं 4-बाइट सीमा; लेकिन, उसी हार्डवेयर पर, जब 64-बिट मोड में संकलित किया जाता है, तो कंपाइलर 8-बाइट सीमा पर double संरेखित होता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow