2011-01-11 22 views
5

मैं एक std::vectorएक वेक्टर

मान लीजिए भरने के तीन तरीके के बारे में सोच सकते हैं भरने के विभिन्न तरीकों पर हम

vector<int> v(100, 0); 

तो मैं इसे पकड़ करना चाहते हैं (1, 1, 1)। हम कर सकते हैं:

v.clear(); 
v.resize(3, 1); 

या

v = vector<int>(3, 1); 

और मैं एक और दृष्टिकोण सीखा:

vector<int>(3, 1).swap(v); 

सबसे पहले सवाल यह है: उनमें से किसी को सबसे अच्छा तरीका है?

दूसरा प्रश्न: मान लें कि v मुख्य समारोह के बाहर घोषित किया गया था। इस answer के अनुसार, डेटा खंड में स्मृति आवंटित की जाएगी। अगर मैं दूसरे या तीसरे दृष्टिकोण का उपयोग करता हूं, तो क्या स्मृति को ढेर पर आवंटित किया जाएगा?

+4

यह बिल्कुल सही नहीं है। आदिम सरणी जहां भी घोषित किए जाते हैं, उनकी याददाश्त आवंटित करते हैं। 'वेक्टर' हमेशा ढेर-आवंटित होगा। int []! = वेक्टर। – Puppy

उत्तर

3

तो, यहां अंतर है और मैं आपको यह तय करने दूंगा कि आपकी स्थिति के लिए सबसे अच्छा क्या है।

v.clear(); 
v.resize(3, 1); 

इस मामले में हमने वेक्टर को साफ़ करने के रूप में चिह्नित किया है। यह अभी भी 100 तत्वों को पकड़ने के लिए जो भी आवंटित किया गया है (जो 100 तत्वों के लिए आवश्यक स्थान से अधिक हो सकता है) रखता है। फिर हमने 1 आइटम के मूल्य के साथ 3 आइटम जोड़े। यह सब आकार काउंटर को बढ़ाता था और 3 मान रीसेट करता था, अंतर्निहित स्मृति अभी भी वही आकार है।

v = vector<int>(3, 1); 

यह करता है काफी सिवाय इसके कि अस्थायी एक अतिरिक्त वेक्टर बनाए जाने और एक ही बात करने के बजाय वहाँ जा रहा है रुक-रुक कर स्थानों पर जहां काउंटर 0 और फिर कुछ मूल्यों के साथ 3 है, यह सरल प्रतियां काउंटर आकार और फिर करता है 3 तत्वों की प्रतिलिपि बनाने के लिए एक memcpy के समान एक ऑपरेशन। वी के लिए आवंटित अंतर्निहित स्मृति का आकार अभी भी 100 पूर्णांक रखने के लिए पर्याप्त है।

vector<int>(3, 1).swap(v); 

यह एक काफी अलग है। इस मामले में हम एक अस्थायी वेक्टर बनाते हैं जिसमें 3 तत्व होते हैं जो सभी को प्रारंभ किया जाता है। सैद्धांतिक रूप से इसमें 100 तत्वों के लिए आरक्षित पर्याप्त स्मृति हो सकती है लेकिन संभावनाएं बहुत कम हैं।फिर हम इस वेक्टर को अपने साथ स्वैप करते हैं और अस्थायी रूप से नष्ट हो जाते हैं। इसमें हमारे पुराने वेक्टर द्वारा आवंटित किसी भी अतिरिक्त मेमोरी को साफ़ करने का अतिरिक्त लाभ है जो अस्थायी नहीं था। जिस तरह से इस काम करता है कि दो वैक्टर (हमारे वी और अस्थायी) बस काउंटर और मूल्यों से अधिक स्वैप है, वे भी बफर संकेत स्वैप।

यह एक वेक्टर हटना करने का एकमात्र तरीका है।

+0

ऐसी संभावना है कि असाइनमेंट ऑपरेटर आंतरिक रूप से स्वैप मुहावरे का भी उपयोग करेगा, जिसके परिणामस्वरूप स्मृति में वही कमी आएगी - हालांकि इसकी गारंटी नहीं है। असल में मुझे नहीं लगता कि आप किसी भी 3 मामलों के साथ कोई गारंटी दे सकते हैं, केवल राज्य ही सबसे अधिक संभावना है। –

2

दूसरे प्रश्न का उत्तर देने के लिए पहले: vector हमेशा उस ऑब्जेक्ट्स के लिए स्मृति को गतिशील रूप से आवंटित करेगा, इसलिए यह ढेर पर समाप्त हो जाएगा।

पुन: असाइन करने की कौन सी विधि बेहतर है, मैं कहूंगा कि आपकी पहली या दूसरी विधि आपके इरादे को सबसे स्पष्ट बनाती है, और यह सबसे महत्वपूर्ण विशेषता है।

9

इस कार्य के लिए वेक्टर के सदस्य का उपयोग कैसे करें?

std::vector<int> v(100); 
v.assign(3, 1); // this is what you should do. 
+0

स्पष्ट को नजरअंदाज करना कितना आसान है। –

+1

यह 'v.clear() का एक छोटा संस्करण है; v.resize (3, 1); 'एक ही अपवाद सुरक्षा समस्या के साथ। –

1

स्वैपिंग प्रभावी रूप से वेक्टर को 3 तत्वों में कम कर देगा। अन्य लोग शायद नहीं करेंगे।

vector<int> v(100); 
v.assign(3, 1); 
assert(v.size() == 3); 
assert(v.capacity() != 3); 

v = vector<int>(3, 1); 
// Now, v.capacity() is likely not to be 3. 

vector<int>(3, 1).swap(v); 
assert(v.capacity() == 3); 

अन्य दृष्टिकोण आंतरिक रूप से वेक्टर का आकार बदल नहीं पाएंगे। यह अभी भी स्मृति में 100 * आकार (int) बाइट्स पर कब्जा करेगा, भले ही आकार() सदस्य रिटर्न 3। अपने आप को मनाने के लिए v.capacity() प्रदर्शित करने का प्रयास करें।

+0

लगभग। हम नहीं जानते कि आकार का आकार वास्तव में इनमें से किसी भी मामले के लिए होगा। कई वेक्टर कार्यान्वयन अतिरिक्त स्थान आरक्षित करते हैं ताकि अक्सर सम्मिलन व्यक्तिगत रूप से पुनर्वितरण और स्थानांतरित न हो। –

1

एक मुद्दा, पिछले पोस्ट में नहीं उल्लेख किया है, इन विकल्पों के बीच चुनने में महत्वपूर्ण है। अर्थात् अपवाद सुरक्षा। vector<int>(3, 1).swap(v); में मजबूत अपवाद सुरक्षा गारंटी है। फॉर्म v = vector<int>(3, 1); स्वैप के मामले में असाइनमेंट लागू होने पर ऐसी गारंटी भी प्रदान कर सकता है। पहला विकल्प सुरक्षित नहीं है: v.clear(); v.resize(3, 1);