যখন ভেক্টরগুলি বরাদ্দ করা হয়, তারা গাদা বা স্ট্যাকের মধ্যে মেমরি ব্যবহার করে?


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
@ ফিলোডাস: আপনার কোড না দেখে এটি নির্ধারণ করা অসম্ভব। একটি নতুন প্রশ্ন খুলুন দয়া করে।
ফ্রেড ফু

2
আমাদের সম্পর্কে vector<Type> vect;যেহেতু উপাদান গাদা হয় এবং হেডার তথ্য স্ট্যাক যখন হেডারের তথ্য ফাংশন রিটার্ন মত, মেমরি থেকে মুছে ফেলা হবে চালু থাকে, তখন কি উপাদান স্মৃতি কি হবে? সেগুলি শিরোনামের তথ্য দিয়ে পুনরায় দাবি করা হয়েছে কি না? যদি তা না হয় তবে কি স্মৃতি ফাঁস হওয়ার কারণ হবে?
ফ্লাইরেন

3
@ ফ্লাইরেন: ভেক্টররা নিজেরাই পরিষ্কার করেন। আরএআইআই পড়ুন ।
ফ্রেড ফু

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পয়েন্টার)।

বিটিডাব্লু বাস্তবায়ন আসলে স্ট্যাকের মধ্যে কিছু ভেক্টর (সাধারণত ছোট আকারের) সংরক্ষণ করতে পারে। এমন কোনও বাস্তবায়ন সম্পর্কে আমি জানি না, তবে এটি পারে।


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);
  }

কোন প্রসঙ্গে আপনার স্ট্যাক থাকবে না? আমি বুঝতে পেরেছি আপনি বলছেন যে মানকটির প্রয়োজন হয় না, তবে ব্যবহারিকভাবে বলতে গেলে আপনি কখন স্ট্যাক ছাড়বেন না?
Nerdtron

3
@ নর্ডট্রন - কয়েকটি ছোট মাইক্রোকন্ট্রোলারের উপর আইআইআরসি আপনার কাছে একটি কল স্ট্যাক রয়েছে যা কোনও আরইটি-র জন্য প্রস্তুত, শেষ কলের পয়েন্টে পিসি (প্রোগ্রাম কাউন্টার) ব্যতীত আর কিছুই সঞ্চয় করতে পারে না। আপনার সংকলক তাই কার্যকরকরণের প্রবাহের সাথে সামান্য / কোনও সম্পর্কযুক্ত একটি স্থিত স্থানে "স্বয়ংক্রিয় স্টোরেজ" (পুনঃ-পুনঃবৃদ্ধিযোগ্য ফাংশনগুলির জন্য) স্থাপন করতে পারেন। এটি পুরো বুদ্ধিমানভাবে পুরো প্রোগ্রামটিকে সমতল করতে পারে। এমনকি পুনরাবৃত্তির ক্ষেত্রে আপনার "ফাংশন প্রতি স্ট্যাক" নীতি বা স্বয়ংক্রিয় ভেরিয়েবল এবং রিটার্ন ঠিকানাগুলির জন্য পৃথক স্ট্যাক থাকতে পারে, যা "স্ট্যাক" শব্দটিকে কিছুটা অর্থহীন করে তোলে।
ফ্লেক্সো

আপনি সমস্ত কিছুর জন্য হ্যাপ ভিত্তিক বরাদ্দ ব্যবহার করতে পারেন এবং একটি "ক্লিনআপ স্ট্যাক" থাকতে পারে যা স্বয়ংক্রিয় স্টোরেজ পরিচালনা করে (এবং সম্ভবত 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; ভেক্টর <ইন্ট *> ভেক্টর; vec.push_back (ptr_to_a); (jpalecek এর উত্তর দেখুন)
ম্যাথু রাসেল

1

ভেক্টর একটি অভ্যন্তরীণ হয়েছে allocatorযা বণ্টন / থেকে স্মৃতি deallocating দায়িত্বে heapজন্য vector element। সুতরাং আপনি কীভাবে ভেক্টর তৈরি করেন তা নির্বিশেষে elementএটি সর্বদা উপর বরাদ্দ করা হয় heap। ভেক্টরের মেটাডেটা হিসাবে, এটি আপনি যেভাবে তৈরি করেছেন তার উপর নির্ভর করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.