2012-05-30 13 views
7

पसंद नहीं मैं कुछ महीनों के लिए मेरे सिर दौर C++ मिल रहा है, और गूगल द्वारा निर्देश दिया गया अतिप्रवाह समय के सबसे C++ प्रश्नों के लिए ढेर करने के लिए है। मैंने "आप वेक्टर का उपयोग क्यों नहीं करते हैं" के अक्सर अनुशंसाओं को नोट करते हैं, और ऐसा करने के लिए प्रेरित थे।C++ वैक्टर सरणियों

तो, मुख्य रूप से स्वत: स्मृति आवंटन रद्द करने, के मामूली लाभ पाने और छँटाई के लिए टाइप किया तुलना कार्यों लिखने के लिए सक्षम होने के लिए। मैंने वेक्टर होने के लिए ऑब्जेक्ट्स के पॉइंटर्स की एक सरणी स्विच की। अब मैंने सोचा था कि (गलत तरीके से ऐसा लगता है) कि वैक्टर इस्तेमाल किया जा सकता और अधिक या कम सरणियों की तरह है, और इसलिए मैं thusly प्रारंभ:

cluster clusters[LOTS]; 
vector<cluster *> pclust; 
pclust.reserve(numClust); 
for (int i=0; i<numClust; ++i) 
    pclust[i] = clusters + i; 

संकलक से कोई शिकायत नहीं। फिर कुछ समय बाद मुझे क्लस्टर ऑब्जेक्ट की कुछ विशेषता पर वेक्टर को सॉर्ट करने की आवश्यकता है। तो:

std::sort(pclust.begin(), pclust.end(), ClusterCompareNumSegs); 

फिर से संकलन करने में कोई समस्या नहीं है। वेक्टर को छोड़कर सॉर्ट नहीं किया गया है। ऐसा लगता है कि vector.size() शून्य, और निश्चित रूप से मेरी प्रारंभ

pclust.push_back(clusters + i); 

अब जब कि ठीक करने के लिए आसान है किया जाना चाहिए था, लेकिन मैं उलझन में हूँ, क्योंकि प्रारंभिक गलत काम काम कर रहा था।

for (clustind=0; clustind < numClust; ++clustind) {<br> 
    cluster *cl = pclust[clustind]; 
    ...happily access *cl... 

और यह सब ठीक काम किया: तो जैसी सरणी सिंटैक्स का उपयोग, - मैं सफलतापूर्वक वेक्टर के माध्यम से दोहराया। तो मैं बस सोच रहा हूं कि क्या हो रहा है। संभवतः मेरे प्रारंभिक असाइनमेंट में, मैं वेक्टर में अभी तक तत्वों तक पहुंचने की कोशिश नहीं कर रहा था (मैं उन्हें अंदर रखने की कोशिश कर रहा था), और वेक्टर उन अपवादों को फेंक रहा था जिन्हें मैं अनदेखा कर रहा था। लेकिन फिर भी, स्थानों का संदर्भ देते समय, पॉइंटर्स वहां थे। क्या कोई ज्ञान प्रदान कर सकता है?

+2

मानक पुस्तकालय बहुत विशाल है, और विशेष रूप से शुरुआत का स्वागत करते हुए नहीं है, मैं सुझाव है कि आप कम से कम कंटेनर प्रकार (http://en.cppreference.com/w/cpp) का दस्तावेज़ पढ़ें - यह आपको बहुत दर्द बचाएगा। – cmannett85

+0

बस दोहराने के लिए, मेरा कोड अब ठीक हो गया है, लेकिन मैं बस – bandjalong

+0

पर सोच रहा था .. अगर कोई भी ऑपरेटर [] के साथ-साथ काम करता है, तो आकार के बिना भी समझा सकता है। शायद वेक्टरों के कंपाइलर (जीसीसी) कार्यान्वयन के साथ बस भाग्यशाली? – bandjalong

उत्तर

11

vector::reserve आपके वेक्टर के आकार को नहीं बदलता है, इसमें अभी भी केवल 0 तत्व शामिल हैं जो इसे बनाए गए थे। यह क्या करता है यह सुनिश्चित कर लें कि वेक्टर संभावित रूप से numClust को पुन: आवंटित किए बिना पकड़ सकें। here देखें।

क्या आप चाहते हैं या तो वेक्टर घोषित करने के लिए है कि आकार

vector<cluster *> pclust(numClust); 

या resize the vector

pclust.resize(numClust); 
+0

कारण मैं आरक्षित कहलाता था क्योंकि मुझे पता था कि मैं कितने तत्व जोड़ने जा रहा था, और वहां पर्याप्त जगह होना चाहता था ताकि उन्हें जोड़ने के दौरान पुनर्वितरण आवश्यक न हो (मैं वास्तव में सरणी की दक्षता चाहता हूं, और सोचा वेक्टर बंद थे पर्याप्त)। – bandjalong

+0

.. लेकिन क्या आप कह रहे हैं कि कॉलिंग आकार बदलने से मुझे सरणी वाक्यविन्यास के साथ प्रारंभ करने की अनुमति मिलती? यदि ऐसा है तो यह अच्छा है (मुझे डर था कि सरणी वाक्यविन्यास को एक लाभा के रूप में उपयोग नहीं किया जा सकता था, जो परेशान होगा)। लेकिन मैं अभी भी सोच रहा हूं कि सरणी क्यों शुरू हुई थी, उसमें डेटा था, लेकिन अभी तक शुरू नहीं हुआ था कि वेक्टर ने सोचा था कि इसका शून्य आकार था ... – bandjalong

+0

@ user1425406: 'ऑपरेटर []' तत्वों को नहीं जोड़ता है एक वेक्टर यह मौजूदा तत्वों का संदर्भ देता है। 'आकार बदलें)' वेक्टर में तत्व जोड़ता है। "प्रारंभ करें" शब्द के बारे में सावधान रहें। सी ++ में जिसका एक बहुत ही विशिष्ट अर्थ है, और वर्ग प्रकारों के लिए जिसका मतलब है कि एक कन्स्ट्रक्टर को कॉल करना। 'एक [3] = बी' असाइनमेंट ऑपरेटर को कॉल करता है, और इसके लिए बाएं हाथ पर पहले से शुरू की गई वस्तु की आवश्यकता होती है। – MSalters

5

std::vector::reserveअनुरोध करने के लिए है कि के तत्वों के लिए आवंटित संग्रहण स्थान की क्षमता वेक्टर कंटेनर कम से कम एन तत्व पकड़ने के लिए पर्याप्त हो। यह वेक्टर का आकार बदलता नहीं है, यही std::vector::resize करता है।

pclust.resize(numClust); के साथ pclust.reserve(numClust); बदलें।

वैकल्पिक रूप से आप pclust.reserve(numClust); को हटा सकते हैं और इस वेक्टर के निर्माण को vector<cluster *> pclust(numClust); में बदल सकते हैं जो समान परिणाम उत्पन्न करता है।

मैं भी सुझाव है कि आप इस सवाल पर एक नजर है करने के लिए: std::vector reserve() and push_back() is faster than resize() and array index, why? :)

+0

आकार बदलने के साथ रिजर्व को बदलने से लक्ष्य (मुझे लगता है) यह सुनिश्चित करने के लिए हल नहीं होगा कि स्मृति की मात्रा का अधिकार आवंटित किया गया है और अब और नहीं (जो मुझे दिमाग में था, साथ ही साथ reallocs से परहेज)। और मैं कन्स्ट्रक्टर को आकार के साथ कॉल नहीं कर सकता, क्योंकि जब निर्माता को बुलाया जाता है तो मुझे आकार पता नहीं होता है। लेकिन यह ठीक है, अब यह सब अच्छा है, मुझे समझ में नहीं आता कि मेरा (गलत) कोड किस तरह काम करता है। – bandjalong

+0

@ user1425406: 'रिजर्व' की तुलना में अधिक स्मृति आवंटित क्यों करें 'आकार बदलें'? इन दोनों के बीच अंतर यह है कि आकार केवल स्मृति को "आरक्षित" नहीं करता बल्कि इन तत्वों का निर्माण भी करता है, इस प्रकार आप 'at() 'या' [] 'का उपयोग करके उन्हें एक्सेस कर सकते हैं। यदि प्रदर्शन वह है जिसे आप ढूंढ रहे हैं, तो 'रिजर्व' +' push_back' के साथ रहें। – LihO

+0

मैंने सोचा था कि रिजर्व की गारंटी दी गई थी कि निर्दिष्ट राशि से अधिक आवंटित न करें, और वह आकार नहीं था। लेकिन अब देखकर, मैं नहीं देख सकता कि मैंने ऐसा क्यों सोचा। तो ठीक है, आकार बदल जाएगा (लेकिन जैसा कि आप सुझाव देते हैं, आरक्षित और push_back सबसे तेज़ है)। असल में मैं चाहता हूं कि संकलक एक ही कोड उत्पन्न करे, जैसा कि आपने एक सरणी शुरू करने के लिए स्पष्ट लूप किया था .. – bandjalong

0

ऑपरेटर [] वेक्टर रिटर्न के साथ इस्तेमाल किया सूचकांक स्थिति पर तत्व को संदर्भित करें। लेकिन, आपने किसी भी मूल्य के साथ वेक्टर शुरू नहीं किया है, इसलिए यह खाली था।

Altough आपने pclust.reserve(numClust) किया है, लेकिन यह केवल इतना बताता है कि वेक्टर का आकार जल्द ही बदल जाएगा और यह अभी तक वेक्टर के आकार को बदलने के बिना स्टोरेज स्पेस आवंटित करता है।

+0

लेकिन यह रहस्य है, [] काम कर रहा था (फैशन के बाद), उन सभी शुरुआती मूल्यों में मैंने जो रखा (जबकि वेक्टर आकार शून्य पर बना रहा), सफलतापूर्वक पुनर्प्राप्त और बाद में संदर्भित किया गया। – bandjalong

0
cluster clusters[LOTS]; 
vector<cluster *> pclust(numClust); 
for (int i = 0; i < numClust; ++i) 
    pclust[i] = clusters + i; 

लेकिन इसका मतलब है कि आप अभी भी क्लस्टर्स को स्टोर करने के लिए एक सरणी का उपयोग कर रहे हैं। क्या आप clusters वेक्टर नहीं बना सकते हैं?

vector<cluster> clusters(LOTS); 
+0

हां मैं कर सकता था, लेकिन मुझे वेक्टर होने का कोई फायदा नहीं दिख रहा है (मैं इसे किसी भी तरह से सॉर्ट नहीं कर सकता, मुझे इसमें डेटा संरचनाओं को क्रमबद्ध करने की आवश्यकता है ...)। – bandjalong

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