जब वैक्टर आवंटित किए जाते हैं, तो वे ढेर या स्टैक पर मेमोरी का उपयोग करते हैं?


151

क्या निम्नलिखित कथन सही हैं?

vector<Type> vect; //allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

कैसे स्मृति के लिए आंतरिक रूप से आवंटित किया जाता है Typeएक में vectorया किसी अन्य एसटीएल कंटेनर?


जवाबों:


222
vector<Type> vect;

vectorस्टैक पर, यानी हेडर की जानकारी, लेकिन फ्री स्टोर ("हीप") पर तत्वों को आवंटित करेगा ।

vector<Type> *vect = new vector<Type>;

मुफ्त स्टोर पर सब कुछ आवंटित करता है।

vector<Type*> vect;

vectorस्टैक पर और फ्री स्टोर पर पॉइंटर्स का एक गुच्छा आवंटित करेगा , लेकिन जहां ये बिंदु निर्धारित किया जाता है कि आप उनका उपयोग कैसे करते हैं (आप फ्री स्टोर में तत्व 0 और स्टैक 1 को तत्व कह सकते हैं)।


3
लेकिन मुझे एक परिदृश्य दिखाई दे रहा है, जहां मुझे दूसरी घोषणा पर बड़ा होने पर एक विभाजन दोष मिल रहा है। मैं मान रहा था कि यह इसलिए था क्योंकि स्टैक पर टाइप आवंटित किया जा रहा था।
फेलोदास

4
@Phelodas: आपके कोड को देखे बिना, इसका आकलन करना असंभव है। कृपया एक नया प्रश्न खोलें।
फ्रेड फू

2
के बारे में vector<Type> vect;के बाद से तत्वों ढेर पर है और हेडर की जानकारी ढेर, जब हैडर जानकारी समारोह वापसी की तरह, स्मृति से निकाल दिया जाता पर है, क्या तत्वों यादों का क्या होगा? क्या उन्हें शीर्ष लेख की जानकारी के साथ पुनः प्राप्त किया गया है या नहीं यदि वे नहीं हैं, तो क्या यह स्मृति रिसाव का कारण होगा?
फ़्लाय्रेन

3
@ क्रिस्टल: वैक्टर खुद के बाद साफ करते हैं। के बारे में पढ़ें आरए II
फ्रेड फू

1
@ क्रिस्टल: काम करना चाहिए। कृपया अधिक विवरण के साथ एक नया प्रश्न पोस्ट करें। यदि आप यहां लिंक पोस्ट करते हैं, तो मैं इसे देख सकता हूं।
फ्रेड फू

25
vector<Type> vect; //allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

नहीं, vectस्टैक पर होगा, लेकिन आइटमों को संग्रहीत करने के लिए आंतरिक रूप से उपयोग की जाने वाली सरणी ढेर पर होगी। आइटम उस सरणी में रहेंगे।

vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

नहीं। ऊपर के रूप में ही, vectorवर्ग को छोड़कर ढेर पर भी होगा।

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

vectस्टैक पर होगा, इसके आइटम (पॉइंटर्स Type) ढेर पर होंगे, और आप यह नहीं बता सकते हैं कि Typeपॉइंटर्स पॉइंट कहां होगा । स्टैक पर हो सकता है, ढेर पर हो सकता है, वैश्विक डेटा में हो सकता है, कहीं नहीं हो सकता (यानी। NULLपॉइंटर्स)।

BTW कार्यान्वयन वास्तव में पूरी तरह से स्टैक पर कुछ वैक्टर (आमतौर पर छोटे आकार के) को स्टोर कर सकता है। ऐसा नहीं है कि मैं ऐसे किसी भी कार्यान्वयन के बारे में जानता हूं, लेकिन यह हो सकता है।


23

एक कार्यान्वयन को मानते हुए जो वास्तव में एक स्टैक और एक ढेर है (मानक सी ++ ऐसी चीजों के लिए कोई आवश्यकता नहीं बनाता है) एकमात्र सही कथन अंतिम है।

vector<Type> vect;
//allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

यह सच है, अंतिम भाग को छोड़कर ( Typeस्टैक पर नहीं होगा)। कल्पना कीजिए:

  void foo(vector<Type>& vec) {
     // Can't be on stack - how would the stack "expand"
     // to make the extra space required between main and foo?
     vec.push_back(Type());
  }

  int main() {
    vector<Type> bar;
    foo(bar);
  }

इसी तरह:

 vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

अंतिम भाग को छोड़कर, समान काउंटर उदाहरण के साथ:

  void foo(vector<Type> *vec) {
     // Can't be on stack - how would the stack "expand"
     // to make the extra space required between main and foo?
     vec->push_back(Type());
  }

  int main() {
    vector<Type> *bar = new vector<Type>;
    foo(bar);
  }

के लिये:

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

यह सच है, लेकिन ध्यान दें कि Type*संकेत ढेर पर होंगे, लेकिन Typeउदाहरण वे इंगित करने की आवश्यकता नहीं है:

  int main() {
    vector<Type*> bar;
    Type foo;
    bar.push_back(&foo);
  }

किस तरह के संदर्भ में आपके पास एक स्टैक नहीं होगा? मैं समझता हूं कि आप कह रहे हैं कि मानक को इसकी आवश्यकता नहीं है, लेकिन व्यावहारिक रूप से, आप बिना स्टैक के कब होंगे?
14

3
@ न्यूडट्रॉन - कुछ छोटे माइक्रोकंट्रोलर पर IIRC आपके पास एक कॉल स्टैक होता है जो RET के लिए तैयार अंतिम कॉल के बिंदु पर पीसी (प्रोग्राम काउंटर) के अलावा कुछ भी स्टोर नहीं कर सकता है। इसलिए आपका संकलक "स्वचालित भंडारण" (गैर-पुनरावर्ती कार्यों के लिए) का चयन कर सकता है, निष्पादन के प्रवाह से कोई संबंध नहीं है। यह काफी समझदारी से पूरे कार्यक्रम को समतल कर सकता है। यहां तक ​​कि पुनरावर्ती मामले के लिए आपके पास "फ़ंक्शन प्रति स्टैक" नीति या स्वचालित चर और वापसी पते के लिए एक अलग स्टैक हो सकता है, जो वाक्यांश "स्टैक" को कुछ अर्थहीन बनाता है।
फ्लेक्सो

आप सब कुछ के लिए हीप आधारित आवंटन का उपयोग कर सकते हैं और एक "सफाई स्टैक" है जो स्वचालित भंडारण (और संभवतः deleteभी) का प्रबंधन करता है ।
फ्लेक्सो

3

केवल यह कथन सत्य है:

vector <Type*> vect; //vect will be on stack and Type* will be on heap.

Type* पॉइंटर्स को ढेर पर आवंटित किया जाता है, क्योंकि पॉइंटर्स की मात्रा गतिशील रूप से बदल सकती है।

vect इस मामले में स्टैक पर आवंटित किया गया है, क्योंकि आपने इसे स्थानीय स्टैक चर के रूप में परिभाषित किया है।


2
प्रकार * हीप आवंटन को इंगित नहीं करता है, बस एक प्रकार की वस्तु के लिए एक संकेतक। उस ने कहा, वेक्टर ढेर पर पॉइंटर को स्टोर करता है। int a = 5; int * ptr_to_a = & a; वेक्टर <int *> vec; vec.push_back (ptr_to_a); (देखें जेपलेसेक का जवाब)
मैथ्यू रसेल

1

वेक्टर में एक आंतरिक allocatorहोता है जो / के heapलिए यादों को आवंटित / डील करने के प्रभारी होता है vector element। तो कोई फर्क नहीं पड़ता कि आप एक वेक्टर कैसे बनाते हैं, इसका elementआवंटन हमेशा किया जाता है heap। वेक्टर के मेटाडेटा के लिए, यह आपके द्वारा बनाए जाने के तरीके पर निर्भर करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.