2012-10-12 16 views
7

पैडिंग की अवधारणा केवल तभी जोड़ा जाता है जब संरचना के कई सदस्य होते हैं और जब कोई मूल डेटा प्रकार सदस्य होता है तो इसमें शामिल क्यों नहीं होता है?संरचनाओं के एकाधिक डेटा सदस्यों के लिए पैडिंग क्यों जोड़ा गया है, न कि एकल सदस्यों के लिए?

अगर हम एक 32 बिट मशीन

struct 
{ 
    char a; 
} Y; 

पर विचार करना कोई पैडिंग नहीं है और sizeof Y 1 बाइट के लिए आता है।

अगर हम इस संरचना पर विचार

struct 
{ 
    char a; 
    int b; 
} X; 

sizeof एक्स 8bytes हो जाएगा।

मेरा प्रश्न दूसरे मामले में पैडिंग क्यों जोड़ रहा था? यदि यह मशीन द्वारा कुशल पहुंच के लिए है जो आम तौर पर 4bytes के गुणकों के ब्लॉक में डेटा पढ़ता है तो पहले मामले में कोई पैडिंग क्यों नहीं थी?

उत्तर

10

दूसरे मामले में पैडिंग जोड़ा जाता है क्योंकि, आपकी मशीन पर, int को 4 बाइट्स के साथ गठबंधन किया जाता है। तो यह करने के लिए 4.

0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 

    a  b  b  b  b  

वाले पते पर विभाज्य है पर रहते हैं करने के लिए कोई गद्दी जोड़ा जाता है है, int सदस्य पता 0x05 पर शुरू होता है, जो गलत है। 3 पैडिंग बाइट्स जोड़ा है:

0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 

    a |  padding  | b  b  b  b 

अब int जो ठीक है 0x08 पर है।

+0

मैं <3 ASCII एआरटी! –

+0

हाय, फिर केस स्ट्रक्चर के बारे में {int b; चार ए; } एक्स; यहां अगर हम 4 से अधिक में मेमोरी लोकेशन से प्रारंभ करने के लिए int और बाद में स्टेट को शुरू करते हैं। पैडिंग भी इस मामले में किया जाता है। यदि सभी डेटामेम्बर सीमा परिस्थितियों का पालन कर रहे हैं तो यहां पैडिंग की आवश्यकता क्यों है? – Laavaa

+1

@ अभिषेक सिंथथ सरणी के कारण। यदि आपके पास 'एक्स एक्स [2]' है, तो दूसरा तत्व - 'x [1] '- को 4 बाइट्स के साथ गठबंधन किया जाना चाहिए क्योंकि इसका पहला सदस्य' int' है, जिसे 4 बाइट्स के साथ गठबंधन किया जाना चाहिए। –

3

यह केवल दक्षता नहीं है।

समस्या प्रति पहुंच का आकार नहीं है, लेकिन यह संरेखण है। ज्यादातर मशीनों पर, गलत संरेखित डेटा तक पहुँचने दुर्घटना करने के लिए कार्यक्रम का कारण होगा, और आज ठेठ मशीनों पर, एक int एक पते एक चार बाइट सीमा पर गठबंधन की आवश्यकता होगी: तक पहुंचने में कोई int जिसका पता है एक चार बाइट सीमा पर गठबंधन नहीं या तो को प्रोग्राम को धीमा कर देगा, या इसे क्रैश कर देगा। आपकी पहली संरचना में संरेखण विचारों वाले किसी भी डेटा नहीं था, इसलिए कोई पैडिंग आवश्यक नहीं था। आपके दूसरे में int है, और संकलक को यह सुनिश्चित करना है कि उनमें से सरणी दी गई हो, int सभी सही ढंग से गठबंधन किए जाएंगे। इसका अर्थ है कि 1) संरचना का कुल आकार चार का एक होना चाहिए, और 2) संरचना में int का ऑफसेट चार में से एक होना चाहिए। (ध्यान में रखते हुए पहली आवश्यकता:

struct S 
{ 
    char a; 
    int b; 
    char c; 
}; 

12 के आकार आम तौर पर होगा, दोनों char के बाद गद्दी के साथ।

struct S 
{ 
    int b; 
    char a; 
    char c; 
}; 
:)

अन्य भाषाओं में, यह अक्सर होता था संकलक structs को पुन: व्यवस्थित करने के लिए इतना है कि सख्त संरेखण आवश्यकताओं के साथ तत्वों struct S के लिए पहले — आया था, इसके बाद के संस्करण, इस के परिणामस्वरूप है |

और 12 के बजाए 8 का आकार, हालांकि सी और सी ++ दोनों इसे मना करते हैं।

+0

हाय, फिर केस स्ट्रक्चर के बारे में {int b; चार ए; } एक्स; यहां अगर हम 4 से अधिक में मेमोरी लोकेशन से प्रारंभ करने के लिए int और बाद में स्टेट को शुरू करते हैं। पैडिंग भी इस मामले में किया जाता है। यदि सभी डेटामेम्बर सीमा परिस्थितियों का पालन कर रहे हैं तो यहां पैडिंग की आवश्यकता क्यों है? – Laavaa

+0

@ अभिषेकसिनाथ ताकि एक सरणी में अगला सदस्य सही ढंग से गठबंधन किया जाएगा। –

0

कुछ डेटा प्रकारों को संरेखित करने के लिए पैडिंग किया जाता है, यानी यह सुनिश्चित करने के लिए कि किसी निश्चित प्रकार के डेटा में एक निर्दिष्ट पता है जो कुछ निर्दिष्ट संख्या का एक बहु है। यह सीपीयू के विभिन्न मॉडलों के बीच भिन्न होता है, लेकिन अक्सर 2-बाइट पूर्णांक उन पते पर गठबंधन होते हैं जो 2 और 4-बाइट पूर्णांक के बहुगुणित होते हैं जो कि 4 के गुणक होते हैं। वर्णों को आम तौर पर गठबंधन करने की आवश्यकता नहीं होती है।

तो यदि संरचना में केवल एक फ़ील्ड है, तब तक जब तक उचित सीमा वाले पते पर संरचना रखी जाती है, तो पैडिंग की कोई आवश्यकता नहीं होती है। और यह हमेशा होगा: सिस्टम हमेशा सबसे बड़ी सीमा के लिए ब्लॉक को संरेखित करता है जिसे कभी भी आवश्यक होगा, आमतौर पर 4 बाइट्स या 8 बाइट्स। संरचना में एक चीज एक उचित सीमा पर होगी। समस्या तब होती है जब आपके पास एकाधिक फ़ील्ड होते हैं, तब एक फ़ील्ड की लंबाई का परिणाम अगले क्षेत्र में उचित सीमा पर नहीं हो सकता है। तो आपके उदाहरण में, आपके पास एक char है, जो निश्चित रूप से 1 बाइट लेता है, और एक int, जो 4 लेता है। मान लीजिए कि संरचना 0x1000 पते पर रखी गई है। फिर बिना पैडिंग के, चार को 0x1000 और int 0x1001 पर रखा जाएगा। लेकिन 4-बाइट सीमाओं पर int int अधिक कुशल होते हैं, इसलिए संकलक कुछ पैड बाइट्स को अगली ऐसी सीमा, 0x1004 पर धक्का देने के लिए जोड़ता है। तो अब आपके पास चार (1 बाइट), पैडिंग (3 बाइट्स), int (4 बाइट्स), कुल 8 बाइट्स हैं।

इस मामले में स्थिति में सुधार करने के लिए आप कुछ भी नहीं कर सकते हैं। प्रत्येक संरचना को 4- या 8-बाइट सीमा से गठबंधन किया जाएगा, इसलिए जब न्यूनतम 5 बाइट्स होता है, तो यह हमेशा अभ्यास में कम से कम 8 तक पहुंचने जा रहा है। (आकार केवल सूत्रों के बीच पैडिंग नहीं दिखाएगा, लेकिन केवल स्मृति खो गया है।)

अन्य मामलों में, आप फ़ील्ड के क्रम को दोबारा व्यवस्थित करके अतिरिक्त पैड बाइट्स की संख्या को कम कर सकते हैं। जैसे कि आपके पास तीन char और तीन int था। आप

struct {char a; int b; char c; int d; char e; int f;} 

के रूप में संरचना की घोषणा तो संकलक पहले चार के बाद 3 बाइट्स जोड़ने पहले पूर्णांक संरेखित करने के लिए, और फिर दूसरा चार के बाद तीन और बाइट्स दूसरा पूर्णांक संरेखित करने के लिए। यह चार (1) + पैड (3) + int (4) + चार (1) + पैड (3) + int (4) + चार (1) + पैड (3) + int (4) = 24.

देता है

लेकिन बजाय आप इसे घोषित करता है, तो:

struct {char a; char c; char e; int b; int d; int f;} 

तो आप चार (1) + चार (1) + चार (1) + पैड (1) + पूर्णांक (4) + पूर्णांक प्राप्त होता (4) + int (4) = 16.

साल पहले मैंने पैडिंग को कम करने के लिए पहले सबसे बड़े तत्वों को रखने के लिए सलाह पढ़ी थी, यानी पहले लम्बे समय, फिर चींटियों, फिर शॉर्ट्स, फिर वर्ण डालें।

यदि आप इनमें से हजारों या लाखों आवंटित कर रहे हैं, तो आप इस तकनीक से बहुत सारी मेमोरी बचा सकते हैं। यदि आप केवल एक या दो आवंटित करने जा रहे हैं, तो इससे कोई फर्क नहीं पड़ता है।

+0

हाय, फिर केस स्ट्रक्चर { int b; चार ए; } एक्स; यहां अगर हम 4 से अधिक में मेमोरी लोकेशन से प्रारंभ करने के लिए int और बाद में स्टेट को शुरू करते हैं। पैडिंग भी इस मामले में किया जाता है। यदि सभी डेटामेम्बर सीमा परिस्थितियों का पालन कर रहे हैं तो यहां पैडिंग की आवश्यकता क्यों है? – Laavaa

+0

@ अभिषेक श्रीनाथ यदि आप उस पर एक आकार देते हैं, तो मुझे लगता है कि आपको 5 मिलेगा, किसी भी पैडिंग का संकेत नहीं होगा। लेकिन जब आप वास्तव में ऐसी वस्तुओं को बनाते हैं, तो ढेर हर ऑब्जेक्ट को सबसे खराब स्थिति सीमा पर 4 या 8 पर संरेखित करने जा रहा है, इसलिए आप अगली ऑब्जेक्ट की शुरुआत में अतिरिक्त 3 बाइट्स के साथ समाप्त होने जा रहे हैं। यह इस बात पर निर्भर हो सकता है कि आप ढेर से अलग वस्तुओं को ऑब्जेक्ट कर रहे हैं, स्टैक पर ऑब्जेक्ट्स या सरणी। मुझे पूरा यकीन है कि पैडिंग सभी कार्यान्वयन-निर्भर है, इसलिए आप विभिन्न प्रणालियों पर अलग-अलग परिणाम प्राप्त कर सकते हैं। बिंदु डेटा संरेखण के लिए सीपीयू की आवश्यकताओं को समायोजित करना है। – Jay

0

Paddingissue of computer efficiency and the speed of the access of the data के लिए, alignment की अवधारणा है, गठबंधन डेटा पूरी तरह से, fetching cycle of the processor from the addresses where the data are stored, it doesn't mean that with out alignment processor doesn't work it only meant for the speed access of the memory के साथ पहुँचा जाता पूर्णांक डेटा के लिए टाइप करें यह है 4 बाइट संरेखण प्रोसेसर के द्वारा और अधिक कुशलता से डेटा का उपयोग करने संकलक द्वारा किया जाता है ।(32 बिट सिस्टम में)

केवल डेटा द्वारा आवश्यक केवल एक बाइट के मामले में संरेखण की कोई आवश्यकता नहीं है क्योंकि प्रत्येक बाइट स्वयं उपलब्ध है (in RAM there are pages and each page size is 1 byte) लेकिन पूर्णांक के लिए हमें 4 बाइट की आवश्यकता है और कोई 4 बाइट सक्षम नहीं है या एक समय में 4 बाइट तक पहुंचने के लिए कुछ भी नहीं कहा जाता है, इसलिए कंपाइलर एक संरेखण नियम बना रहा है जिसके द्वारा पूर्णांक डेटा सही पते पर हैं।

और जिसके द्वारा यह डेटा को तेज़ी से स्मृति पहुंच प्रदान करेगा।

+0

आप मनमाने ढंग से शब्दों को कोड/प्री-टैग में क्यों डालते हैं? क्या आप अपने स्रोतों को नाम देना भूल गए? –

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