2010-10-24 26 views
5

एसटीएल वेक्टर आमतौर पर कैसे लागू किया जाता है? इसमें char [] का कच्चा भंडारण होता है जिसे कभी-कभी एक निश्चित कारक द्वारा आकार दिया जाता है और फिर तत्व को धक्का दिया जाता है जब एक तत्व धक्का होता है (एक बहुत ही रोचक व्याकरणिक रूप मुझे ध्यान रखना चाहिए - भाषाविदों को push_back के रूप में ऐसे क्रिया रूपों का अध्ययन करना चाहिए :)
और तो संरेखण आवश्यकताओं हैं। तो एक प्राकृतिक सवाल उठता है कि मैं एक char [] पर नया प्लेसमेंट कैसे कॉल कर सकता हूं और सुनिश्चित कर सकता हूं कि संरेखण आवश्यकताओं को संतुष्ट किया गया हो। इसलिए मैं शब्द "संरेखण" के लिए 2003 के सी ++ मानक खोज की है और इन पाया:चार सरणी का संरेखण

पैरा 3.9 खण्ड 5

वस्तु प्रकार संरेखण आवश्यकताओं (3.9.1, 3.9.2) है। एक पूर्ण ऑब्जेक्ट प्रकार का संरेखण एक कार्यान्वयन-परिभाषित पूर्णांक मान है जो कई बाइट्स का प्रतिनिधित्व करता है; किसी ऑब्जेक्ट को उस पते पर आवंटित किया जाता है जो उसके ऑब्जेक्ट प्रकार की संरेखण आवश्यकताओं को पूरा करता है।

पैरा 5.3.4 खंड 10:

एक नई अभिव्यक्ति प्रकार एसटीडी का पहला तर्क :: size_t के रूप में आवंटन समारोह करने का अनुरोध स्थान की मात्रा से गुजरता है। वह तर्क वस्तु के आकार के आकार से कम नहीं होगा; यह ऑब्जेक्ट के आकार से बड़ा हो सकता है केवल ऑब्जेक्ट एक सरणी है। चार और हस्ताक्षरित चार के सरणी के लिए, नई अभिव्यक्ति के परिणाम और आवंटन फ़ंक्शन द्वारा दिए गए पते के बीच का अंतर किसी ऑब्जेक्ट प्रकार की सबसे कड़े संरेखण आवश्यकता (3.9) का एक अभिन्न अंग होगा जिसका आकार कोई बड़ा नहीं है सरणी का आकार बनाया जा रहा है। [नोट: चूंकि आवंटन फ़ंक्शंस को पॉइंटर्स को वापस स्टोरेज में माना जाता है जो कि किसी भी प्रकार की ऑब्जेक्ट्स के लिए उचित रूप से गठबंधन किया जाता है, सरणी आवंटन ओवरहेड पर यह बाधा चरित्र सरणी आवंटित करने के सामान्य मुहावरे को अनुमति देती है जिसमें अन्य प्रकार की वस्तुओं को बाद में रखा जाएगा। ]

इन दोनों मेरे ऊपर प्रश्न के लिए एक पूरी तरह से संतोषजनक जवाब दे, लेकिन ...

Statement1:
प्रकार एक्स का एक उद्देश्य के लिए एक संरेखण आवश्यकता जहां sizeof (एक्स) == n कम से कम है आवश्यकता है कि एक्स का पता एन द्वारा विभाजित किया जा सकता है या ऐसा कुछ (सभी वास्तुकला-निर्भर चीज़ों को "या उस तरह कुछ" में डाल दें)।

Question1: कृपया, इस बात की पुष्टि परिष्कृत करते हैं, या इसके बाद के statement1 इंकार करते हैं।

स्टेटमेंट 2: यदि कथन 1 मानक में दूसरे उद्धरण से सही है तो यह 5000000 वर्णों के एक पते पर 5000000 वर्णों की एक सरणी आवंटित की जाती है जो पूरी तरह से अनावश्यक है यदि मुझे केवल चार की तरह सरणी की आवश्यकता है, अन्य वस्तुओं के संभावित प्लेसमेंट के लिए एक कच्चे भंडारण के रूप में।

Question2: तो, सफलतापूर्वक 1000 वर्ण वास्तव में की तुलना में कम 500 शॉर्ट्स आवंटन की संभावना कर रहे हैं (कम प्रदान की 2 बाइट्स है)? क्या यह वास्तव में एक समस्या है?

उत्तर

3

प्रकार एक्स का एक उद्देश्य के लिए एक संरेखण आवश्यकता जहां sizeof (एक्स) == n कम से कम आवश्यकता है कि का पता एक्स n या की तरह कुछ से विभाज्य है कि

नहीं। किसी प्रकार की संरेखण आवश्यकता हमेशा इसके आकार का एक कारक है, लेकिन इसके आकार के बराबर नहीं होने की आवश्यकता है। यह आमतौर पर कक्षा के सभी सदस्यों की संरेखण आवश्यकताओं के सबसे बड़े के बराबर होता है।

अपने खाते पर 5 एम चार की एक सरणी के लिए केवल 1 की संरेखण आवश्यकता की आवश्यकता होती है, जो एक char की संरेखण आवश्यकता के समान होती है।

तो, पाठ आप वैश्विक ऑपरेटर new, के माध्यम से आबंटित स्मृति के संरेखण के बारे में बोली प्रभाव में इसका मतलब है कि एक बड़े आवंटन किसी भी प्रकार के सबसे कड़े संरेखण आवश्यकता का पालन करना चाहिए (और malloc हालांकि IIRC नहीं समान आवश्यकता के लिए एक समान है) प्रणाली में। इसके अलावा, कार्यान्वयन अक्सर इस से बड़े सिम प्रकार को बाहर करते हैं, और सिम के लिए उस स्मृति की विशेष रूप से आवंटित की आवश्यकता होती है। यह थोड़ा संदिग्ध है, लेकिन मुझे लगता है कि वे इस आधार पर इसे औचित्य देते हैं कि गैर मानक, विस्तार प्रकार मनमाने ढंग से विशेष आवश्यकताओं को लागू कर सकते हैं।

तो व्यवहार में नंबर जो आपको लगता है 5000000 है अक्सर 4 :-)

1

प्रश्न 1: संरेखण आकार से संबंधित नहीं है।

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

+0

@Let_Me_Be है: कारण मैं संरेखण चाहिए ** ** आकार से संबंधित है कि अगर मैं एक्स के की एक सरणी लेने के लिए और उन सभी को संरेखण आवश्यकताओं का पालन करना चाहिए, फिर पते, ए + आकार (एक्स), ए + 2 * आकार (एक्स) ... आदि सभी को इन आवश्यकताओं को अनुरूप बनाना चाहिए। जिसने मुझे बयान को परिभाषित करने का नेतृत्व किया। क्या मै गलत हु? –

+0

@ आर्मेन: आप इसे उल्टा कर चुके हैं। ऑब्जेक्ट का आकार इसके संरेखण का एक बहु होना चाहिए। एक 'char' में आमतौर पर संरेखण 1 होता है, और' int 'को आमतौर पर 4-बाइट सीमा पर गठबंधन किया जाना होता है। दोनों 'युक्त' संरचना 'को इसके सबसे सख्ती से गठबंधन सदस्य का संरेखण दिया जाता है (इसलिए यदि इसमें' char' और 'int' है, तो पूरी तरह से संरचना को एक 'संरेखण' के समान संरेखण की आवश्यकता होती है)। ऑब्जेक्ट के बाद भी एक आकार होना चाहिए जो एक int के कुछ बहु है। आपके विशाल चार सरणी के लिए भी यही सच है। इसमें वर्णों के अलावा कुछ भी नहीं है, और प्रत्येक चार को किसी भी बाइट (किसी भी पते को 1 से विभाजित किया जा सकता है) – jalf

+0

पर रखा जा सकता है, इसलिए पूरी तरह से सरणी में समान संरेखण आवश्यकता होती है (और 1 का एक से अधिक होना चाहिए, जो मुश्किल नहीं है प्राप्त करने के लिए।)) – jalf

4

जब आप गतिशील स्मृति operator new का उपयोग कर आवंटन, आप गारंटी है कि:

सूचक लौटे उपयुक्त रूप से गठबंधन किया जाएगा ताकि यह किसी भी पूरा ऑब्जेक्ट प्रकार का एक सूचक में बदला जा सकता है और फिर उपयोग करने के लिए इस्तेमाल किया भंडारण में ऑब्जेक्ट या सरणी आवंटित (जब तक कि स्टोरेज को किसी कॉल द्वारा स्पष्ट रूप से किसी डीलोकेशन फ़ंक्शन पर अस्वीकार नहीं किया जाता है) (सी ++ 03 3.7.3.1/2)।

vector char की एक सरणी नहीं बनाता है; यह एक आवंटक का उपयोग करता है। डिफॉल्ट आवंटक स्मृति आवंटित करने के लिए ::operator new का उपयोग करता है।

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