2010-08-13 16 views
22
vector <weight> decoy; 

void clear_decoy() { 

    decoy.clear(); 

    vector<weight> (decoy).swap(decoy); 
} 

उपरोक्त विधि clear_decoy() में, vector<weight> (decoy).swap(decoy); का क्या मतलब है?सी ++ वेक्टर :: स्पष्ट

क्या विधि decoy स्पष्ट है या नहीं? धन्यवाद! उनके विनाशकर्ता कहा जाता है, और फिर वे वेक्टर कंटेनर से निकाल दिए जाते हैं, 0 से आकार के साथ कंटेनर छोड़ने:

+0

उन उत्तरों को स्वीकार करना याद रखें जिन्हें आप चेकमार्क पर क्लिक करके सबसे अच्छा महसूस करते हैं –

उत्तर

20

यह Weight ऑब्जेक्ट्स (जो खाली होगा) का एक नया वेक्टर बनाता है और decoy के साथ इसे स्वैप करता है।

इसका कारण यह है कि डिफ़ॉल्ट रूप से std::vector<t>::clear वास्तव में वेक्टर द्वारा उपयोग किए जाने वाले संग्रहण को कम नहीं करता है, यह केवल वहां मौजूद सभी वस्तुओं को नष्ट कर देता है। इस तरह, वेक्टर में भविष्य में पुनर्वितरण के बिना अधिक वस्तुओं को स्टोर करने के लिए कमरा है।

कभी-कभी, आप वेक्टर में क्षमता को ट्रिम करना चाहते हैं। एक नव निर्मित वेक्टर (जो इसकी रेखा के अंत तक रहता है, और इसलिए वहां नष्ट हो जाता है) के साथ स्वैपिंग वेक्टर द्वारा आवंटित सभी स्मृति को मुक्त करता है।

+1

ओह प्रिय! मेरे प्रिय सी ++, आप उन लोगों के लिए परेशानी करते हैं जो हमारे से ज्यादा चालाक होने से आपको प्यार करते हैं। –

+0

स्मार्ट होने के नाते सामाजिक लागत है। – Klaim

+1

यह बहुत सी ++ वाई है। सी ++ मेमोरी मैनेजमेंट का खुलासा करता है ताकि आपके पास अपनी जरूरतों के लिए चीजों को कस्टमाइज़ करने का मौका मिले। डिफ़ॉल्ट रूप से C++ जितना तेज़ हो सकता है, और इसलिए यदि आप इस कोड का पालन नहीं करते हैं तो आपको तेज़ कोड मिल जाएगा। ऐसे मामलों में जहां आपके पास बहुत बड़ा वेक्टर है और आप इसके कई तत्वों को हटाते हैं, तो आप गति के खर्च पर ओएस को मुक्त संसाधनों के लिए इस मुहावरे का उपयोग कर सकते हैं। आम तौर पर आप ऐसा नहीं करना चाहते हैं (यानी, जो टूटा नहीं है उसे ठीक न करें)। – wilhelmtell

1
स्पष्ट साथ

,

सभी वेक्टर के तत्वों गिरा रहे हैं।

स्वैप सिर्फ दो वैक्टर,

तैर स्वैप एपी सामग्री

वीसी की सामग्री द्वारा वेक्टर की सामग्री का आदान-प्रदान करता है, जो एक ही प्रकार के वेक्टर है। आकार भिन्न हो सकते हैं।

इस सदस्य कार्य करने के लिए कॉल के बाद, इस कंटेनर में तत्व उन जो कॉल करने से पहले vec में थे हैं, और vec के तत्वों उन जो इस में हुआ था। सभी इटरेटर, संदर्भ और पॉइंटर्स स्वैप किए गए वैक्टर के लिए मान्य रहते हैं।

ऐसा लगता है कि आप वास्तव में कुछ भी स्वैप नहीं कर रहे हैं और केवल डिफ़ॉल्ट आवंटन में पुनर्स्थापित कर रहे हैं। साफ़ हटाया जा सकता है लेकिन यह कभी-कभी नहीं करता है। आप न केवल आकार को कम कर रहे हैं बल्कि स्वैप कथन के साथ आवंटित स्थान को कम कर रहे हैं।

+0

क्या स्मृति जारी है? – ladyfafa

+0

@ladyfafa: स्वैप स्टेटमेंट के साथ, आवंटित स्थान की मात्रा कम हो जाती है। यह वैक्टर का अच्छा हिस्सा है। –

+0

मैं देखता हूं, धन्यवाद !! – ladyfafa

6

clear वेक्टर से सभी प्रविष्टियों को हटा देता है, लेकिन संभवतः अंतरिक्ष को डिलीकेट नहीं कर सकता है। यह स्वैप मुहावरे वेक्टर को आवंटित करने के लिए वेक्टर को पुनर्स्थापित करता है।

+3

वास्तव में 'स्पष्ट' * वेक्टर पर कब्जा कर सकते हैं स्थान को हटा सकते हैं। लेकिन यह * करने के लिए * नहीं है। यह आमतौर पर ज्यादातर एसटीएल कार्यान्वयन में नहीं है। –

+0

@ बिली ओनेल: धन्यवाद। मैंने अपना जवाब संपादित किया। –

22

मैंने पहले कभी ऐसा फॉर्म नहीं देखा है।

मैं इसे के रूप में लिखा देखा है:।

vector<weight>().swap(decoy); 

जिसका मतलब है "एक नया खाली वेक्टर बनाते हैं, और मौजूदा एक के साथ यह स्वैप

vector<weight> (decoy).swap(decoy);

को समझने के लिए कि, में तोड़ने भागों के लिए।

vector<weight>(decoy) एक नया वेक्टर बनाएं (इसकी सामग्री अब खाली डेको से कॉपी की गई है)। नया वेक्टर एक असाधारण अस्थायी है, इसलिए आइए इसका नाम दें newvector

newVector.swap(decoy); नए वेक्टर को डीकॉपी के साथ बदल देता है।

+3

+1 एक ही चीज़ के बेहतर (और अधिक) सामान्य निर्माण का सुझाव देने के लिए +1। –

+2

यह 'वेक्टर () .swap (decoy) 'होना चाहिए। आप अस्थायी पर सदस्य फ़ंक्शंस को कॉल कर सकते हैं, लेकिन आप उन्हें गैर-कॉन्स्ट संदर्भ तर्क के रूप में पास नहीं कर सकते हैं। –

+0

+1 मैं एक खराब टाइपिस्ट हूं। :) –

10

कि कोड स्मृति द्वारा वेक्टर मुक्त हो जाता है आवंटित सुनिश्चित करने के लिए एक आम चाल का उपयोग करने के एक असफल प्रयास है (बग को ठीक करने की टिप्पणियां प्रति अद्यतन किया गया)। यह वास्तव में ऐसा नहीं कर सकता है या नहीं, वेक्टर की प्रतिलिपि निर्माता अन्य वेक्टर के आकार, या इसकी क्षमता से मेल खाने के लिए स्मृति आवंटित करता है या नहीं।

मज़बूती से स्मृति मुक्त करने के लिए, का उपयोग करें:

void clear_decoy() { 
    vector<weight>().swap(decoy); 
} 

यह एक अस्थायी खाली वेक्टर (आवंटित कम या कोई स्मृति के साथ) बनाता है, decoy ताकि स्मृति अब अस्थायी के स्वामित्व में है के साथ इस स्वैप , फिर स्मृति को मुक्त करने, अस्थायी को नष्ट कर देता है।

+0

उत्कृष्ट बिंदु। –

+1

हालांकि यह सच है, कोई क्षमता एसटीएल कार्यान्वयन यहां क्षमता के आधार पर आवंटित करने जा रहा है। –

+0

@ बिली: दरअसल; बेकार स्पष्ट-प्रति-स्वैप नृत्य काम करने की बहुत संभावना है, लेकिन सरल संस्करण काम करने की गारंटी है। –

3

0 ए0 डी उल्लेख के रूप में, swap का प्रभाव दो वैक्टरों के बीच अंतर्निहित नियंत्रित स्मृति का आदान-प्रदान करना है। लेकिन यह थोड़ा और स्पष्टीकरण वारंट करता है।

जब आप clearvector, कम से कम जहां तक ​​प्रोग्रामर का संबंध है, उससे तत्व हटा दिए जाते हैं। size() शून्य हो जाता है और capacity() बदल सकता है या नहीं भी। लेकिन मानक गारंटी नहीं देता है कि वेक्टर द्वारा उपयोग की जाने वाली मेमोरी वास्तव में ऑपरेटिंग सिस्टम पर वापस आ जाएगी। इसलिए clear() से पहले वेक्टर में 1000 तत्व थे और clear() प्रत्येक तत्व के विनाशक के नाम के बाद प्रत्येक 1000 बाइट्स मेमोरी लेता था, लेकिन वेक्टर अभी भी 1,000,000 बाइट आवंटन पर हो सकता है।

यह कभी-कभी अवांछनीय है। उपरोक्त नोट 'स्वैप चाल' में दो वैक्टरों के बीच नियंत्रित स्मृति का आदान-प्रदान करने का प्रभाव होता है। इसलिए decoy इसके नियंत्रित मेमोरी रीसेट के साथ समाप्त होता है।

  1. decoy तत्व एक erased हैं:

    यहाँ क्या कदम-दर-कदम हो रहा है। तत्वों के विनाशक कहा जाता है, और वेक्टर के size() शून्य हो जाता है। वास्तविक स्मृति को हटाया नहीं जा सकता है।

  2. स्टैक पर एक नया वेक्टर बनाया गया है (vector<weight> (decoy)) और decoy के तत्वों की प्रतिलिपि बनाई गई है। चूंकि decoy केवल clear() एड था, अस्थायी वेक्टर में कोई तत्व कॉपी नहीं किया गया था। हालांकि, नीचे संपादित देखें देखें। आप नहीं जानते कि नियंत्रित स्मृति स्वैप नहीं है।
  3. अस्थायी वेक्टर और decoy की स्मृति स्वैप की गई है (.swap(decoy);) जिसके परिणामस्वरूप decoy दोनों साफ़ हो गए हैं और इसकी स्मृति अस्थायी में स्थानांतरित हो गई है।
  4. अस्थायी रूप से ढेर से गिर जाता है, जिसके परिणामस्वरूप इसकी स्मृति को हटा दिया जाता है।

इसे "the swap trick" के रूप में जाना जाता है।

संपादित करें: जैसा कि माइक का उल्लेख है, मूल प्रोग्रामर इसे गलत कर रहा है। अस्थायी का निर्माण decoy के आधार पर नहीं किया जाना चाहिए, इसे केवल डिफ़ॉल्ट रूप से बनाया जाना चाहिए। आप निश्चित रूप से नहीं जानते कि swap() केवल तत्वों की प्रतिलिपि बनाएगा, न कि नियंत्रित स्मृति के नीचे।

+0

+1 ग्रेट स्पष्टीकरण –

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