2012-09-04 13 views
63

में वेक्टर की आरंभिक क्षमता std::vector का capacity() क्या है जो डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करके बनाई गई है? मुझे पता है कि size() शून्य है। क्या हम बता सकते हैं कि एक डिफ़ॉल्ट निर्मित वेक्टर ढेर स्मृति आवंटन को कॉल नहीं करता है?सी ++

इस तरह एक एकल आवंटन का उपयोग करके एक मनमानी रिजर्व के साथ एक सरणी बनाना संभव होगा, जैसे std::vector<int> iv; iv.reserve(2345);। मान लीजिए कि किसी कारण से, मैं नहीं चाहता कि, 2345.

उदाहरण के लिए पर size() शुरू करने के लिए लिनक्स (छ ++ 4.4.5, कर्नेल 2.6.32 amd64)

#include <iostream> 
#include <vector> 

int main() 
{ 
    using namespace std; 
    cout << vector<int>().capacity() << "," << vector<int>(10).capacity() << endl; 
    return 0; 
} 

मुद्रित 0,10 पर चाहते हैं। क्या यह एक नियम है, या यह एसटीएल विक्रेता निर्भर है?

+6

मानक वेक्टर की प्रारंभिक क्षमता के बारे में कुछ भी निर्दिष्ट नहीं करता है लेकिन अधिकांश कार्यान्वयन 0 का उपयोग करते हैं। –

+8

कोई गारंटी नहीं है, लेकिन मैं किसी भी कार्यान्वयन की गुणवत्ता पर गंभीरता से सवाल करता हूं जो बिना किसी अनुरोध के स्मृति आवंटित करता है। –

+0

@ माइकसेमोर असहमत। वास्तव में उच्च प्रदर्शन कार्यान्वयन में एक छोटा इनलाइन बफर हो सकता है, जिसमें प्रारंभिक क्षमता() को सेट करने के मामले में यह समझदारी होगी। – alastair

उत्तर

46

मानक निर्दिष्ट नहीं करता है कि कंटेनर के प्रारंभिक capacity क्या होना चाहिए, इसलिए आप कार्यान्वयन पर निर्भर हैं। एक सामान्य कार्यान्वयन शून्य पर क्षमता शुरू करेगा, लेकिन इसकी कोई गारंटी नहीं है। दूसरी ओर std::vector<int> iv; iv.reserve(2345); की अपनी रणनीति को बेहतर बनाने का कोई तरीका नहीं है, इसलिए इसके साथ चिपके रहें।

+1

मैं आपका अंतिम बयान नहीं खरीदता हूं। यदि आप प्रारंभ में 0 होने की क्षमता पर भरोसा नहीं कर सकते हैं, तो आप अपने प्रोग्राम को पुन: स्थापित कर सकते हैं ताकि आपके वेक्टर को प्रारंभिक आकार हो सके। यह ढेर-मेमोरी अनुरोधों की आधा संख्या (2 से 1 तक) होगी। – bitmask

+4

@bitmask: व्यावहारिक होने के नाते: क्या आप * किसी * कार्यान्वयन के बारे में जानते हैं जहां डिफ़ॉल्ट कन्स्ट्रक्टर में स्मृति आवंटित एक वेक्टर? यह मानक द्वारा गारंटी नहीं है, लेकिन माइक सेमुर की आवश्यकता के बिना आवंटन को ट्रिगर करने के संकेत के रूप में * कार्यान्वयन की गुणवत्ता * के बारे में एक बुरा गंध होगा। –

+2

@ डेविडरोद्रिगुएज़-ड्राईबीस: यह बात नहीं है। आधार था "आप अपनी वर्तमान रणनीति से बेहतर नहीं कर सकते हैं, इसलिए सोचें कि क्या * बेवकूफ कार्यान्वयन हो सकता है"। यदि आधार था "ऐसे कोई कार्यान्वयन नहीं हैं, इसलिए परेशान न करें" मैं इसे खरीदूंगा। निष्कर्ष सच होता है, लेकिन निहितार्थ काम नहीं करता है। क्षमा करें, शायद मैं नाइट पिकिंग कर रहा हूँ। – bitmask

15

std :: वेक्टर के भंडारण कार्यान्वयन में काफी भिन्नता है, लेकिन सभी लोगों को मैं से 0.

निम्नलिखित कोड शुरू का सामना करना पड़ा:

:

#include <iostream> 
#include <vector> 

int main() 
{ 
    using namespace std; 

    vector<int> normal; 
    cout << normal.capacity() << endl; 

    for (unsigned int loop = 0; loop != 10; ++loop) 
    { 
     normal.push_back(1); 
     cout << normal.capacity() << endl; 
    } 

    std::cin.get(); 
    return 0; 
} 

निम्नलिखित उत्पादन देता है

0 
1 
2 
4 
4 
8 
8 
8 
8 
16 
16 
जीसीसी 5.1 के तहत

और:

0 
1 
2 
3 
4 
6 
6 
9 
9 
9 
13 

MSVC 2013 के तहत

+3

ओह अच्छा, वे 0 पर शुरू करने के लिए पर्याप्त स्मार्ट थे। – Andrew

+2

यह बहुत कम है @ एंड्रयू –

+0

अच्छी तरह से आप लगभग हर जगह पाते हैं कि गति उद्देश्यों की सिफारिश लगभग हमेशा एक वेक्टर का उपयोग करने के लिए होती है, इसलिए यदि आप कुछ भी कर रहे हैं जिसमें स्पैस डेटा शामिल है ... – Andrew

2

अन्य उत्तर देने के लिए एक मामूली इसके अलावा के रूप में, मैंने पाया कि जब दृश्य स्टूडियो के साथ डिबग शर्तों के तहत चल रहे एक डिफ़ॉल्ट का निर्माण वेक्टर अभी भी ढेर पर आवंटित करेगा भले ही क्षमता शून्य पर शुरू होता है।

विशेष रूप से अगर _ITERATOR_DEBUG_LEVEL! = 0 तो वेक्टर पुनरावर्तक जांच में सहायता के लिए कुछ स्थान आवंटित करेगा।

https://docs.microsoft.com/en-gb/cpp/standard-library/iterator-debug-level

मैं सिर्फ यह थोड़ा कष्टप्रद के बाद से मैं समय में एक कस्टम संभाजक उपयोग कर रहा था और अतिरिक्त आवंटन उम्मीद नहीं थी पाया।

+0

दिलचस्प, वे अस्वीकरण को तोड़ते हैं- गारंटी देता है (कम से कम सी + 17 के लिए, पहले?): http://en.cppreference.com/w/cpp/container/vector/vector – Deduplicator

0

मानक क्षमता के लिए प्रारंभिक मूल्य निर्दिष्ट नहीं करता है लेकिन एसटीएल कंटेनर स्वचालित रूप से जितना डेटा डालता है उतना डेटा समायोजित करने के लिए बढ़ता है, बशर्ते आप अधिकतम आकार (अधिकतम_साइज सदस्य फ़ंक्शन को जानने के लिए) से अधिक न हों। वेक्टर और स्ट्रिंग के लिए, जब भी अधिक जगह की आवश्यकता होती है तो विकास को पुनर्विक्रय द्वारा नियंत्रित किया जाता है। मान लीजिए कि आप एक वेक्टर होल्डिंग वैल्यू 1-1000 बनाना चाहते हैं। रिजर्व का उपयोग कर के बिना, कोड को आमतौर पर निम्नलिखित पाश दौरान 18 2 के बीच और reallocations में परिणाम होगा:

vector<int> v; 
v.reserve(1000); 

for (int i = 1; i <= 1000; i++) v.push_back(i); 

मोटे तौर पर:

vector<int> v; 
for (int i = 1; i <= 1000; i++) v.push_back(i); 

आरक्षित उपयोग करने के लिए लूप के दौरान 0 आवंटन हो सकती कोड संशोधित कहने के लिए, वेक्टर और स्ट्रिंग क्षमताओं प्रत्येक समय 1.5 और 2 के बीच एक कारक से बढ़ते हैं।