সি ++ এ স্ট্যাক, স্ট্যাটিক এবং হিপ


160

আমি অনুসন্ধান করেছি, তবে আমি এই তিনটি ধারণা খুব ভালভাবে বুঝতে পারি নি। কখন আমাকে গতিশীল বরাদ্দ ব্যবহার করতে হবে (গাদাতে) এবং এর আসল সুবিধাটি কী? স্ট্যাটিক এবং স্ট্যাকের সমস্যাগুলি কী? আমি কীভাবে গাদাতে ভেরিয়েবল বরাদ্দ না করে একটি সম্পূর্ণ অ্যাপ্লিকেশন লিখতে পারি?

আমি শুনেছি যে অন্য ভাষাগুলিতে একটি "আবর্জনা সংগ্রহকারী" অন্তর্ভুক্ত করা হয় যাতে আপনার স্মৃতি সম্পর্কে চিন্তা করতে হবে না। আবর্জনা সংগ্রহকারী কী করবেন?

আপনি এই ময়লা আবর্জনা সংগ্রহকারীকে ব্যবহার করতে না পেরে নিজের দ্বারা স্মৃতিচারণ করতে কী করতে পারেন?

একবার এই ঘোষণা দিয়ে কেউ আমাকে বলেছিল:

int * asafe=new int;

আমার একটি "পয়েন্টার টু পয়েন্টার" আছে। এর মানে কী? এটির থেকে আলাদা:

asafe=new int;

?


কিছুক্ষণ আগে খুব অনুরূপ প্রশ্ন করা হয়েছিল: স্ট্যাক এবং হিপ কী এবং কোথায়? এই প্রশ্নের কয়েকটি সত্যই ভাল উত্তর রয়েছে যা আপনার উপর কিছুটা আলোকপাত করতে পারে।
স্কট সাদ

উত্তর:


223

অনুরূপ একটি প্রশ্ন জিজ্ঞাসা করা হয়েছিল, তবে এটি স্ট্যাটিক্স সম্পর্কে জিজ্ঞাসা করে না।

স্থিতিশীল, গাদা এবং স্ট্যাক মেমরি কীসের সংক্ষিপ্তসার:

  • একটি স্ট্যাটিক ভেরিয়েবল মূলত একটি গ্লোবাল ভেরিয়েবল, এমনকি আপনি বিশ্বব্যাপী এটি অ্যাক্সেস করতে না পারলেও। সাধারণত এটির জন্য একটি ঠিকানা থাকে যা নিজেই কার্যকর করতে সক্ষম হয়। পুরো প্রোগ্রামটির জন্য কেবল একটি অনুলিপি রয়েছে। আপনি কতবার কোনও ফাংশন কল (বা ক্লাস) এ যান (এবং কতগুলি থ্রেডে!) ভেরিয়েবল একই মেমরির অবস্থান উল্লেখ করছে matter

  • হিপ মেমরির একগুচ্ছ যা গতিশীলভাবে ব্যবহার করা যেতে পারে। আপনি যদি কোনও সামগ্রীর জন্য 4 কেবি চান তবে গতিশীল বরাদ্দকারী তার স্তূপের ফাঁকা স্থানের তালিকাটি অনুসন্ধান করবে, একটি 4 কেবি অংশ বেছে নেবে এবং এটি আপনাকে দেবে। সাধারণত, গতিশীল মেমরি বরাদ্দকারী (ম্যালোক, নতুন, এবং সি।) মেমরির শেষে শুরু হয় এবং পিছনের দিকে কাজ করে।

  • কীভাবে একটি স্ট্যাক বৃদ্ধি এবং সঙ্কুচিত হয় এই ব্যাখ্যাটির উত্তরের বাইরে কিছুটা নয়, তবে আপনি সর্বদা যুক্ত এবং কেবল শেষ থেকে সরাবেন বলে যথেষ্ট। স্ট্যাকগুলি সাধারণত উচ্চ থেকে শুরু হয় এবং নীচে ঠিকানাগুলিতে বেড়ে যায়। স্ট্যাকটি মধ্যবর্তী কোথাও গতিশীল বরাদ্দকারীর সাথে মিলিত হয়ে গেলে আপনি মেমরির বাইরে চলে যান (তবে শারীরিক বনাম ভার্চুয়াল মেমরি এবং খণ্ডগুলি দেখুন)। একাধিক থ্রেডের জন্য একাধিক স্ট্যাকের প্রয়োজন হবে (প্রক্রিয়াটি সাধারণত স্ট্যাকের জন্য সর্বনিম্ন আকার সংরক্ষণ করে)।

আপনি যখন প্রতিটি ব্যবহার করতে চান:

  • স্ট্যাটিকস / গ্লোবালগুলি মেমরির জন্য দরকারী যে আপনি জানেন যে আপনার সর্বদা প্রয়োজন হবে এবং আপনি জানেন যে আপনি কখনই বিলোপ করতে চান না। (যাইহোক, এম্বেড করা পরিবেশগুলি কেবল স্থির মেমরির হিসাবে বিবেচিত হতে পারে ... স্ট্যাক এবং হিপ একটি তৃতীয় মেমরি টাইপের দ্বারা ভাগ করা একটি পরিচিত ঠিকানা জায়গার অংশ: প্রোগ্রাম কোড Prog প্রোগ্রামগুলি প্রায়শই তাদের বাইরে থেকে গতিশীল বরাদ্দ করবে) স্থিতিশীল স্মৃতি যখন তাদের লিঙ্কযুক্ত তালিকার মতো জিনিসগুলির প্রয়োজন হয়।তবে নির্বিশেষে, স্ট্যাটিক মেমরি নিজেই (বাফার) নিজেই "বরাদ্দকৃত" নয়, বরং এই উদ্দেশ্যে বাফারের ধারণকৃত স্মৃতি থেকে অন্য অবজেক্টগুলি বরাদ্দ করা হয় আপনি এটি করতে পারেন can এম্বেডবিহীন পাশাপাশি, এবং কনসোল গেমগুলি প্রায়শই সমস্ত বরাদ্দের জন্য প্রসেট আকারের বাফার ব্যবহার করে বরাদ্দ প্রক্রিয়াটি দৃly়ভাবে নিয়ন্ত্রণের পক্ষে গতিশীল মেমরি পদ্ধতিতে অন্তর্নির্মিতকে আটকাবে))

  • স্ট্যাক ভেরিয়েবলগুলি যখন আপনি জানেন যে ফাংশনটি সুযোগের মধ্যে রয়েছে (কোথাও স্ট্যাকের উপরে), আপনি ভেরিয়েবলগুলি বজায় রাখতে চান। স্ট্যাকগুলি ভেরিয়েবলগুলির জন্য দুর্দান্ত যা আপনার যে কোডে অবস্থিত সেগুলির জন্য প্রয়োজন তবে সেই কোডটির বাইরে যা প্রয়োজন নেই। আপনি যখন কোনও ফাইলের মতো কোনও সংস্থান অ্যাক্সেস করছেন তখন এগুলি সত্যিই দুর্দান্ত এবং আপনি যখন এই কোডটি ছেড়ে যান তখন সংস্থানটি স্বয়ংক্রিয়ভাবে চলে যেতে চাইবে।

  • আপনি উপরের তুলনায় আরও নমনীয় হতে চাইলে গাদা বরাদ্দ (গতিশীল বরাদ্দ মেমরি) কার্যকর হয়। প্রায়শই, একটি ইভেন্টের প্রতিক্রিয়া জানাতে একটি ফাংশন ডেকে আনা হয় (ব্যবহারকারী "তৈরি বাক্স" বোতামটি ক্লিক করেন)। যথাযথ প্রতিক্রিয়াটির জন্য একটি নতুন অবজেক্ট (নতুন বক্স অবজেক্ট) বরাদ্দের প্রয়োজন হতে পারে যা ফাংশনটি বের হওয়ার অনেক পরে থাকতে পারে, সুতরাং এটি স্ট্যাকের মধ্যে থাকতে পারে না। প্রোগ্রামটির শুরুতে আপনি কতগুলি বাক্স চাইবেন তা আপনি জানেন না, সুতরাং এটি কোনও স্ট্যাটিক হতে পারে না।

আবর্জনা সংগ্রহ

আবর্জনা সংগ্রহকারীরা কত দুর্দান্ত সে সম্পর্কে আমি ইদানীং অনেক শুনেছি, তাই কিছুটা ভিন্নমত পোষণকারী ভয়েস সহায়ক হতে পারে।

কর্মক্ষমতা যখন কোনও বিশাল সমস্যা না হয় তার জন্য আবর্জনা সংগ্রহের একটি দুর্দান্ত প্রক্রিয়া। আমি শুনেছি জিসিগুলি আরও ভাল এবং পরিশীলিত হচ্ছে, তবে আসল বিষয়টি হল, আপনি কোনও পারফরম্যান্স পেনাল্টি (ব্যবহারের ক্ষেত্রে নির্ভর করে) গ্রহণ করতে বাধ্য হতে পারেন। এবং যদি আপনি অলস হন তবে এটি এখনও সঠিকভাবে কাজ করতে পারে না। সর্বোত্তম সময়ে, আবর্জনা সংগ্রহকারীরা বুঝতে পারে যে আপনার স্মৃতি যখন চলে যায় তখন বুঝতে পারে যে এর সাথে আর কোনও উল্লেখ নেই ( রেফারেন্স গণনা দেখুন)। তবে, যদি আপনার কাছে এমন কোনও অবজেক্ট থাকে যা নিজেকে উল্লেখ করে (সম্ভবত অন্য কোনও বস্তু যা আবার উল্লেখ করে) তবে কেবল রেফারেন্স গণনা ইঙ্গিত দেয় না যে স্মৃতি মুছে ফেলা যায় can এই ক্ষেত্রে, জিসিকে সম্পূর্ণ রেফারেন্স স্যুপটি দেখতে হবে এবং এমন কোনও দ্বীপ রয়েছে যা কেবল নিজেরাই উল্লেখ করা হয়েছে কিনা তা খুঁজে বের করতে হবে। অফহ্যান্ড, আমি অনুমান করতাম যে এটি একটি (এন ^ 2) অপারেশন হবে, তবে এটি যাই হোক না কেন, আপনি যদি পারফরম্যান্সের সাথে উদ্বিগ্ন হন তবে এটি খারাপ হতে পারে। (সম্পাদনা: মার্টিন বি পয়েন্ট আউট এটা যুক্তিসঙ্গতভাবে দক্ষ আলগোরিদিম জন্য O (ঢ) হয় যে এখনো হে (ঢ হয়) অত্যধিক যদি আপনার কর্মক্ষমতা সঙ্গে সংশ্লিষ্ট করা হয় এবং আবর্জনা সংগ্রহ ছাড়া ধ্রুব সময় ডি-এলোকেট পারবেন না।।)

ব্যক্তিগতভাবে, আমি যখন শুনি লোকেরা বলে যে সি ++ এর আবর্জনা সংগ্রহ নেই, তখন আমার মন ট্যাগ করে যে সি ++ এর বৈশিষ্ট্য হিসাবে, তবে আমি সম্ভবত সংখ্যালঘুতে আছি। সি এবং সি ++ তে প্রোগ্রামিং সম্পর্কে লোকেরা শেখার পক্ষে সম্ভবত সবচেয়ে কঠিন বিষয় হ'ল পয়েন্টার এবং কীভাবে তাদের গতিশীল মেমরির বরাদ্দ সঠিকভাবে পরিচালনা করতে হয়। পাইথনের মতো আরও কিছু ভাষা জিসি ছাড়াই ভয়ঙ্কর হবে, তাই আমি মনে করি যে আপনি কোন ভাষা থেকে কী চান তা নেমে আসে। আপনি যদি নির্ভরযোগ্য পারফরম্যান্স চান, তবে আবর্জনা সংগ্রহ ছাড়াই সি ++ হ'ল ফোর্টরানের এই দিকটি আমি ভাবতে পারি। আপনি যদি ব্যবহারের সহজ এবং প্রশিক্ষণের চাকাগুলি চান ("যথাযথ" মেমরি পরিচালনা শেখার প্রয়োজন ছাড়াই ক্র্যাশ থেকে বাঁচাতে), একটি জিসি সহ কিছু চয়ন করুন। এমনকি আপনি কীভাবে মেমরির পরিচালনা করতে ভাল জানেন তা আপনার সময় সাশ্রয় করবে যা আপনি অন্যান্য কোডের অনুকূলকরণে ব্যয় করতে পারবেন। সত্যিকার অর্থে পারফরম্যান্সের খুব বেশি পেনশন নেই, তবে আপনার যদি নির্ভরযোগ্য পারফরম্যান্সের প্রয়োজন হয় (এবং ঠিক কী চলছে তা জানার দক্ষতা, কখন, কভারের আওতায়) তবে আমি সি ++ দিয়ে থাকি। এমন একটি কারণ রয়েছে যে আমি যে বড় বড় গেম ইঞ্জিনের কথা শুনেছি সেগুলি সি ++ (যদি সি বা সমাবেশ না হয়) থাকে। পাইথন, এট আল স্ক্রিপ্টিংয়ের জন্য ভাল তবে মূল গেম ইঞ্জিন নয়।


এটি আসল প্রশ্নের সাথে সত্যই প্রাসঙ্গিক নয় (বা বেশিরভাগ ক্ষেত্রেই আসলে) তবে আপনি স্ট্যাকের অবস্থান এবং পিছনের দিকে গাদা পেয়েছেন। সাধারণত , স্ট্যাকটি নীচে নেমে যায় এবং গাদা বড় হয় (যদিও একটি গাদা আসলে "বড় হয় না", তাই এটি একটি বিশাল ওভারসাম্প্লিকেশন))
পি ড্যাডি

আমি মনে করি না যে এই প্রশ্নটি একই রকম বা অন্য প্রশ্নের সদৃশ। এটি একটি বিশেষত সি ++ সম্পর্কে এবং তার অর্থ কী ছিল তা নিশ্চিতভাবেই সি ++ তে বিদ্যমান তিনটি স্টোরেজ সময়কাল। আপনার স্থিতিশীল মেমোরিতে ঠিক একটি সূক্ষ্ম বরাদ্দ থাকতে পারে, উদাহরণস্বরূপ, ওভারলোড অপটি নতুন new
জোহানেস স্কাউব - লিটব

7
আপনার আবর্জনা সংগ্রহের অবমাননাকর চিকিত্সা সহায়ক থেকে কিছুটা কম ছিল।
পি বাবা

9
প্রায়শই আবর্জনা সংগ্রহ আজকাল ম্যানুয়াল মুক্ত করার মেমরির চেয়ে ভাল কারণ যখন খুব কম কাজ করা হয় তখন ঘটে থাকে, মেমরি মুক্ত করার বিপরীতে যা ঘটতে পারে অন্যথায় পারফরম্যান্সটি ব্যবহার করা যেতে পারে right
জর্জি স্কলি 21

3
কেবলমাত্র একটি ছোট্ট মন্তব্য - আবর্জনা সংগ্রহের ক্ষেত্রে ও (এন ^ 2) জটিলতা নেই (এটি কার্যত পারফরম্যান্সের জন্য বিপর্যয়কর হবে)। একটি আবর্জনা সংগ্রহের চক্রের জন্য নেওয়া সময়টি গাদা আকারের সমানুপাতিক - hpl.hp.com/personal/Hans_Boehm/gc/complexity.html দেখুন
মার্টিন বি

54

নিম্নলিখিতটি অবশ্যই সমস্তগুলি যথাযথ নয়। আপনি যখন এটি পড়বেন তখন লবণের এক দানা দিয়ে নিয়ে যান :)

ভাল, আপনি যে তিনটি বিষয় উল্লেখ করেছেন তা হ'ল স্বয়ংক্রিয়, স্থিতিশীল এবং গতিশীল স্টোরেজ সময়কাল , যার কতক্ষণ অবজেক্টগুলি বেঁচে থাকে এবং কখন তারা জীবন শুরু করে তার সাথে কিছু সম্পর্ক রয়েছে।


স্বয়ংক্রিয় স্টোরেজ সময়কাল

আপনি স্বল্পকালীন এবং ছোট ডেটার জন্য স্বয়ংক্রিয় স্টোরেজ সময়কাল ব্যবহার করেন , এটি কেবলমাত্র কিছু ব্লকের মধ্যে স্থানীয়ভাবে প্রয়োজন :

if(some condition) {
    int a[3]; // array a has automatic storage duration
    fill_it(a);
    print_it(a);
}

আমরা ব্লক থেকে প্রস্থান করার সাথে সাথে জীবনকাল শেষ হয়ে যায় এবং অবজেক্টটি সংজ্ঞায়িত হওয়ার সাথে সাথে এটি শুরু হয়। এগুলি হ'ল স্টোরেজ সময়কালের সবচেয়ে সাধারণ ধরণের এবং নির্দিষ্ট গতিশীল স্টোরেজ সময়কালের চেয়ে বেশ দ্রুত গতিযুক্ত।


স্ট্যাটিক স্টোরেজ সময়কাল

আপনি স্থিতিশীল স্টোরেজ সময়কাল ফ্রি ভেরিয়েবলের জন্য ব্যবহার করেন যা কোনও কোড দ্বারা সর্বদা অ্যাক্সেস করা হতে পারে, যদি তাদের স্কোপ এ জাতীয় ব্যবহারের (নাম স্পেস স্কোপ) অনুমতি দেয় এবং স্থানীয় ভেরিয়েবলগুলির জন্য যা তাদের স্কোপ (স্থানীয় সুযোগ) থেকে বেরিয়ে যাওয়ার সময়কালে তাদের আজীবন প্রসারিত করতে পারে এবং সদস্য ভেরিয়েবলগুলির জন্য যা তাদের শ্রেণীর সমস্ত শ্রেণীর (শ্রেণির ক্ষেত্র) ভাগ করে নেওয়া দরকার। তাদের জীবদ্দশায় তারা যে স্কোপ রয়েছে তার উপর নির্ভর করে They তাদের নেমস্পেসের সুযোগ এবং স্থানীয় সুযোগ এবং শ্রেণির সুযোগ থাকতে পারে । এই দু'জনের ক্ষেত্রে যা সত্য তা হ'ল একবার তাদের জীবন শুরু হওয়ার পরে প্রোগ্রামটির শেষে জীবনকাল শেষ হয় । এখানে দুটি উদাহরণ দেওয়া হল:

// static storage duration. in global namespace scope
string globalA; 
int main() {
    foo();
    foo();
}

void foo() {
    // static storage duration. in local scope
    static string localA;
    localA += "ab"
    cout << localA;
}

প্রোগ্রামটি মুদ্রণ করে ababab, কারণ localAএটির ব্লকটি প্রস্থান করার পরে ধ্বংস হয় না। আপনি বলতে পারেন যে স্থানীয় অবকাশ রয়েছে এমন অবজেক্টগুলি যখন তাদের সংজ্ঞাতে পৌঁছায় আজীবন শুরু হয় । কারণ localA, যখন ফাংশনের শরীরে প্রবেশ করা হয় তখন এটি ঘটে। নাম স্পেসের অবজেক্টগুলির জন্য, জীবনকাল প্রোগ্রামের শুরুতে শুরু হয় । শ্রেণীর সুযোগের স্থির বস্তুর ক্ষেত্রেও এটি একই:

class A {
    static string classScopeA;
};

string A::classScopeA;

A a, b; &a.classScopeA == &b.classScopeA == &A::classScopeA;

যেমন আপনি দেখতে পাচ্ছেন, classScopeAএটি তার শ্রেণীর নির্দিষ্ট বিষয়গুলির সাথে সীমাবদ্ধ নয়, বরং শ্রেণীর মধ্যেই। উপরের তিনটি নামের ঠিকানা একই এবং সমস্ত একই জিনিসকে বোঝায়। স্থির অবজেক্টগুলি কখন এবং কীভাবে শুরু করা হয় সে সম্পর্কে বিশেষ নিয়ম রয়েছে তবে আসুন এখন সে বিষয়ে উদ্বেগ প্রকাশ করা উচিত নয়। এটি স্ট্যাটিক ইনিশিয়ালাইজেশন অর্ডার ফিয়াসক শব্দটি দ্বারা বোঝানো হয়েছে ।


গতিশীল স্টোরেজ সময়কাল

শেষ সঞ্চয়ের সময়কাল গতিশীল। আপনি যদি অন্য আইল্যান্ডে অবজেক্টগুলি থাকতে চান তবে আপনি এটি ব্যবহার করেন এবং আপনি সেই রেফারেন্সের চারদিকে পয়েন্টার রাখতে চান। আপনার জিনিসগুলি বড় হলে আপনি সেগুলিও ব্যবহার করেন এবং আপনি যদি রানটাইমে পরিচিত আকারের অ্যারেগুলি তৈরি করতে চান তবে । এই নমনীয়তার কারণে, গতিশীল স্টোরেজ সময়কালযুক্ত অবজেক্টগুলি জটিল এবং পরিচালনা করতে ধীর হয়। যখন কোনও উপযুক্ত নতুন অপারেটরের অনুরোধ ঘটে তখন সেই গতিশীল সময়কালীন অবজেক্টগুলি আজীবন শুরু হয়:

int main() {
    // the object that s points to has dynamic storage 
    // duration
    string *s = new string;
    // pass a pointer pointing to the object around. 
    // the object itself isn't touched
    foo(s);
    delete s;
}

void foo(string *s) {
    cout << s->size();
}

আপনি যখন তাদের জন্য মুছুন কল করুন তখনই তার জীবনকাল শেষ হবে । যদি আপনি এটি ভুলে যান তবে সেই জিনিসগুলি কখনই আজীবন শেষ হয় না। এবং শ্রেণীর অবজেক্টস যা কোনও ব্যবহারকারী ঘোষিত কনস্ট্রাক্টরকে সংজ্ঞায়িত করে তাদের ডিস্ট্রাক্টরদের ডাকা হবে না। গতিশীল স্টোরেজ সময়কালীন অবজেক্টগুলির জন্য তাদের জীবনকাল এবং সম্পর্কিত মেমরি রিসোর্সের ম্যানুয়াল হ্যান্ডলিং প্রয়োজন। এগুলির ব্যবহার সহজ করার জন্য গ্রন্থাগারগুলি বিদ্যমান। নির্দিষ্ট সামগ্রীর জন্য স্পষ্ট আবর্জনা সংগ্রহ একটি স্মার্ট পয়েন্টার ব্যবহার করে প্রতিষ্ঠিত করা যেতে পারে:

int main() {
    shared_ptr<string> s(new string);
    foo(s);
}

void foo(shared_ptr<string> s) {
    cout << s->size();
}

কলটি মুছে ফেলা সম্পর্কে আপনার কোনও চিন্তা করার দরকার নেই: ভাগ করা পিটিআর এটি আপনার জন্য করে, যদি শেষ পয়েন্টারটি উল্লেখ করে যে বস্তুটি সুযোগের বাইরে চলে যায়। ভাগ করা পিটিআর এর স্বয়ংক্রিয় স্টোরেজ সময়কাল। সুতরাং এর জীবনকালটি স্বয়ংক্রিয়ভাবে পরিচালিত হয়, এটি এটির পরীক্ষককে বিন্দুতে গতিশীল অবজেক্টটি মুছতে হবে কিনা তা যাচাই করার অনুমতি দেয়। Shared_ptr অবগতির জন্য, বুস্ট নথি দেখুন: http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm


39

এটি "সংক্ষিপ্ত উত্তর" হিসাবে বিস্তৃতভাবে বলা হয়েছে:

  • স্ট্যাটিক ভেরিয়েবল (শ্রেণি)
    আজীবন = প্রোগ্রাম রানটাইম (1)
    দৃশ্যমানতা = অ্যাক্সেস পরিবর্তনকারী দ্বারা নির্ধারিত (ব্যক্তিগত / সুরক্ষিত / পাবলিক)

  • স্ট্যাটিক ভেরিয়েবল (গ্লোবাল স্কোপ)
    আজীবন = প্রোগ্রাম রানটাইম (1)
    দৃশ্যমানতা = সংকলন ইউনিট এটি ইনস্ট্যান্ট হয় (2)

  • হিপ ভেরিয়েবল
    আজীবন = আপনার দ্বারা সংজ্ঞায়িত (মুছতে নতুন)
    ভিজিবিলিটি = আপনার দ্বারা সংজ্ঞায়িত (আপনি যা নির্দেশককে নির্ধারণ করেন)

  • স্ট্যাক ভেরিয়েবল
    ভিজিবিলিটি = ঘোষণার থেকে স্কোপটি
    আজীবন না হওয়া পর্যন্ত = ঘোষণার থেকে ঘোষণার সুযোগ ছাড়ার আগ পর্যন্ত


(1) আরও ঠিক: সূচনা থেকে সংকলন ইউনিট (যেমন সি / সি ++ ফাইল) ডিনিটায়ালাইজেশন পর্যন্ত। সংকলন ইউনিট প্রারম্ভিক ক্রম মান দ্বারা সংজ্ঞায়িত করা হয় না।

(২) সাবধান: আপনি যদি একটি শিরোনামে স্ট্যাটিক ভেরিয়েবল ইনস্ট্যান্ট করেন তবে প্রতিটি সংকলন ইউনিট তার নিজস্ব অনুলিপি পায়।


5

আমি নিশ্চিত যে পেন্টেন্টগুলির মধ্যে একটি শীঘ্রই আরও ভাল উত্তর নিয়ে আসবে, তবে মূল পার্থক্য গতি এবং আকার।

গাদা

বরাদ্দ নাটকীয়ভাবে দ্রুত। এটি ও (1) এ সম্পন্ন করা হয়েছে যেহেতু এটি স্ট্যাক ফ্রেম সেট আপ করার সময় বরাদ্দ করা হয় তাই এটি মূলত নিখরচায়। অসুবিধাটি হ'ল আপনি যদি স্ট্যাক স্পেসের বাইরে চলে যান তবে আপনাকে ধর্ষণ করা হবে। আপনি স্ট্যাকের আকারটি সামঞ্জস্য করতে পারেন তবে আইআইআরসি আপনার সাথে খেলতে ~ 2MB রয়েছে। এছাড়াও, আপনি ফাংশন থেকে প্রস্থান করার সাথে সাথে স্ট্যাকের সমস্ত কিছুই সাফ হয়ে যায়। সুতরাং পরে এটি উল্লেখ করা সমস্যাযুক্ত হতে পারে। (বরাদ্দ হওয়া বস্তুগুলিকে স্ট্যাক করার পয়েন্টারগুলি বাগের দিকে নিয়ে যায়।)

গাদা

বরাদ্দ নাটকীয়ভাবে ধীর। তবে আপনার সাথে খেলতে জিবি রয়েছে এবং নির্দেশ করুন।

আবর্জনা সংগ্রহকারী

আবর্জনা সংগ্রাহক এমন কিছু কোড যা ব্যাকগ্রাউন্ডে চলে এবং মেমরি মুক্ত করে। আপনি যখন গাদাতে মেমরি বরাদ্দ করেন তখন এটি মুক্ত করা ভুলে যাওয়া খুব সহজ, যা মেমরি ফুটো হিসাবে পরিচিত। সময়ের সাথে সাথে, আপনার অ্যাপ্লিকেশনটি যে স্মৃতি গ্রহণ করে তা ক্রাশ না হওয়া অবধি বাড়তে থাকে এবং বেড়ে যায়। কোনও আবর্জনা সংগ্রহকারী আপনার পর্যায়ক্রমে মেমরি মুক্ত করে দেয় যা আপনার আর প্রয়োজন নেই এই শ্রেণীর বাগগুলি দূর করতে সহায়তা করে। অবশ্যই এটি একটি দামে আসে, কারণ আবর্জনা সংগ্রহকারী জিনিসগুলি ধীর করে দেয়।


3

স্ট্যাটিক এবং স্ট্যাকের সমস্যাগুলি কী?

"স্থিতিশীল" বরাদ্দের সমস্যাটি হ'ল এই বরাদ্দটি সংকলন-সময়ে করা হয়: আপনি কিছু পরিবর্তনশীল সংখ্যক ডেটা বরাদ্দ করতে এটি ব্যবহার করতে পারবেন না, যার সংখ্যা রান-টাইম অবধি জানা যায় না।

"স্ট্যাক" এ বরাদ্দ করার ক্ষেত্রে সমস্যাটি হ'ল বরাদ্দটি সাব্রোটাইন যা বরাদ্দটি ফেরত দেয় তত তাড়াতাড়ি ধ্বংস হয়ে যায়।

আমি স্তূপে ভেরিয়েবলগুলি বরাদ্দ না করে একটি সম্পূর্ণ অ্যাপ্লিকেশন লিখতে পারি?

সম্ভবত তবে একটি তুচ্ছ, সাধারণ, বড় অ্যাপ্লিকেশন নয় (তবে তথাকথিত "এম্বেডেড" প্রোগ্রামগুলি সি ++ এর উপসেট ব্যবহার করে গাদা ছাড়া লেখা যেতে পারে)।

আবর্জনা সংগ্রহকারী কী করেন?

এটি কখন আপনার অ্যাপ্লিকেশন আর উল্লেখ করে না তা সনাক্ত করার জন্য এটি আপনার ডেটা ("চিহ্ন এবং সুইপ") পর্যবেক্ষণ করে। এটি অ্যাপ্লিকেশনটির জন্য সুবিধাজনক, কারণ অ্যাপ্লিকেশনটির ডেটা হ্রাস করার দরকার নেই ... তবে আবর্জনা সংগ্রহকারী গণনা ব্যয়বহুল হতে পারে।

আবর্জনা সংগ্রহকারীরা সি ++ প্রোগ্রামিংয়ের স্বাভাবিক বৈশিষ্ট্য নয়।

আপনি এই ময়লা আবর্জনা সংগ্রহকারীকে ব্যবহার করতে না পেরে নিজের দ্বারা স্মৃতিচারণ করতে কী করতে পারেন?

ডিটারমিনিস্টিক মেমোরি ক্ষয় করার জন্য সি ++ প্রক্রিয়া শিখুন:

  • 'স্থিতিশীল': কখনও অবরুদ্ধ হয় না
  • 'স্ট্যাক': ভেরিয়েবল "সুযোগের বাইরে চলে যাওয়ার সাথে সাথে"
  • 'হিপ': যখন পয়েন্টারটি মুছে ফেলা হয় (অ্যাপ্লিকেশন দ্বারা স্পষ্টভাবে মুছে ফেলা হয়, বা কিছু বা অন্য সাবরুটিনের মধ্যে স্পষ্টভাবে মুছে ফেলা হয়)

1

স্ট্যাক মেমরি বরাদ্দ (ফাংশন ভেরিয়েবল, স্থানীয় ভেরিয়েবল) সমস্যাযুক্ত হতে পারে যখন আপনার স্ট্যাকটি খুব "গভীর" থাকে এবং আপনি স্ট্যাক বরাদ্দে উপলভ্য মেমরিটিকে উপচে ফেলে দেন। গাদা হ'ল এমন বস্তুগুলির জন্য যা একাধিক থ্রেড থেকে বা পুরো প্রোগ্রাম জুড়ে অ্যাক্সেস করতে হবে। আপনি গাদা ব্যবহার না করে একটি সম্পূর্ণ প্রোগ্রাম লিখতে পারেন।

কোনও আবর্জনা সংগ্রহকারী ছাড়াই আপনি মেমরিটি খুব সহজেই ফাঁস করতে পারেন তবে বস্তু এবং মেমরিটি মুক্ত হয়ে গেলে আপনি ডিক্টর করতে পারেন। আমি যখন জাসিটি চালায় তখন আমি জাভা নিয়ে ইস্যুতে অংশ নিয়েছি এবং আমার একটি বাস্তব সময় প্রক্রিয়া রয়েছে, কারণ জিসি একটি একচেটিয়া থ্রেড (অন্য কিছুই চালাতে পারে না)। সুতরাং যদি পারফরম্যান্স সমালোচনা হয় এবং আপনি গ্যারান্টি দিতে পারেন যে কোনও ফাঁস হওয়া অবজেক্ট নেই, জিসির ব্যবহার না করা খুব সহায়ক। অন্যথায় এটি আপনার জীবনকে ঘৃণা করে তোলে যখন আপনার অ্যাপ্লিকেশনটি মেমরি গ্রাস করে এবং আপনাকে একটি ফাঁসের উত্সটি সন্ধান করতে হয়।


1

যদি আপনার প্রোগ্রামটি কতটা মেমরি বরাদ্দ করতে হয় তা সম্মুখভাগে না জানে (অতএব আপনি স্ট্যাক ভেরিয়েবলগুলি ব্যবহার করতে পারবেন না)। লিঙ্কযুক্ত তালিকাগুলি বলুন, তালিকাগুলির আকার কী তা না জেনেও বাড়তে পারে। সুতরাং কোনও গাদা পরিমাণে বরাদ্দ করা কোনও লিঙ্কযুক্ত তালিকার জন্য অর্থপূর্ণ হয় যখন আপনি জানেন না যে এতে কতগুলি উপাদান .োকানো হবে।


0

কিছু পরিস্থিতিতে জিসির সুবিধা অন্যদের মধ্যে বিরক্তি; জিসির উপর নির্ভরতা এ বিষয়ে বেশি চিন্তা না করার জন্য উত্সাহ দেয়। তত্ত্ব অনুসারে, 'অলস' সময়কালের জন্য বা এটি একেবারে অবধি হওয়া পর্যন্ত অপেক্ষা করে, যখন এটি ব্যান্ডউইথকে চুরি করবে এবং আপনার অ্যাপ্লিকেশনটিতে প্রতিক্রিয়া বিলম্ব করবে।

তবে আপনাকে 'এটি নিয়ে ভাবেন না'। ঠিক যেমন মাল্টিথ্রেডেড অ্যাপ্লিকেশনগুলিতে রয়েছে আপনি যখন ফলন করতে পারবেন তখন আপনি ফলন করতে পারবেন। সুতরাং উদাহরণস্বরূপ। নেট, একটি জিসির অনুরোধ করা সম্ভব; এটি করে, কম ঘন ঘন দীর্ঘতর চলমান জিসির পরিবর্তে, আপনি আরও ঘন ঘন কম চালিত জিসি রাখতে পারেন এবং এই ওভারহেডের সাথে যুক্ত ল্যাটেন্সটি ছড়িয়ে দিতে পারেন।

তবে এটি জিসির প্রাথমিক আকর্ষণকে পরাভূত করে যা "এটি অটো-ম্যাট-আইসি বলে এটি সম্পর্কে খুব বেশি চিন্তা না করার জন্য উত্সাহিত করা হয়েছে" বলে মনে হয়।

আপনি যদি জিসি প্রচলিত হয়ে ওঠার আগে প্রথম প্রোগ্রামিংয়ের মুখোমুখি হয়েছিলেন এবং ম্যালোক / ফ্রি এবং নতুন / মুছে ফেলার বিষয়ে স্বাচ্ছন্দ্য বোধ করেন তবে আপনারা জিসিকে কিছুটা বিরক্তিকর এবং / অথবা অবিশ্বাস্য বলে মনে করেন (যেহেতু কেউ 'অবিশ্বস্ত হতে পারে') অপ্টিমাইজেশন, 'যা একটি চেক ইতিহাস আছে।) অনেক অ্যাপ্লিকেশন এলোমেলোভাবে বিলম্বিতা সহ্য করে। তবে যে অ্যাপ্লিকেশনগুলি না, যেখানে এলোমেলোভাবে বিলম্ব হওয়া কম গ্রহণযোগ্য, সেখানে একটি সাধারণ প্রতিক্রিয়া হ'ল জিসি পরিবেশগুলি রোধ করা এবং নিখুঁতভাবে পরিচালনা না করা কোডের দিকে চালিত করা (বা forbশ্বর নিষেধ করুন, একটি দীর্ঘকালীন শিল্প, সমাবেশ ভাষা) language

আমি এখানে কিছুক্ষণ আগে গ্রীষ্মের এক ছাত্র ছিলাম, একজন ইন্টার্ন, স্মার্ট বাচ্চা, যাকে জিসি থেকে ছাড়ানো হয়েছিল; তিনি জিসির উত্সাহ সম্পর্কে এতটাই মীমাংসিত ছিলেন যে নিয়ন্ত্রণহীন সি / সি ++ তে প্রোগ্রামিং করার সময়ও তিনি ম্যালোক / ফ্রি নতুন / মুছনীয় মডেলটি অনুসরণ করতে অস্বীকার করেছিলেন কারণ, "আপনার আধুনিক প্রোগ্রামিং ভাষায় এটি করা উচিত নয়।" এবং তুমি জানো? ক্ষুদ্র, স্বল্প চলমান অ্যাপ্লিকেশনগুলির জন্য, আপনি প্রকৃতপক্ষে এটি থেকে দূরে সরে যেতে পারেন, তবে দীর্ঘ চলমান পারফরম্যান্ট অ্যাপ্লিকেশনগুলির জন্য নয়।


0

স্ট্যাক হ'ল সংকলক দ্বারা বরাদ্দকৃত একটি মেমরি, যখনই আমরা প্রোগ্রামটি সংকলন করি, ডিফল্ট সংকলক ওএস থেকে কিছু মেমরি বরাদ্দ করে (আমরা আপনার আইডিইতে সংকলক সেটিংস থেকে সেটিংস পরিবর্তন করতে পারি) এবং ওএস আপনাকে মেমরি দেয় যা তার নির্ভর করে সিস্টেমে প্রচুর উপলভ্য মেমরি এবং অন্যান্য অনেকগুলি জিনিস এবং স্ট্যাক মেমরির জন্য বরাদ্দ হয় যখন আমরা কোনও ভেরিয়েবলের অনুলিপি করি (ফর্মাল হিসাবে এটি প্রতিস্থাপন করে) সেই ভেরিয়েবলগুলিকে স্ট্যাকের জন্য চাপ দেওয়া হয় তারা ডিফল্টরূপে কিছু নামকরণ কনভেনশন অনুসরণ করে ভিজ্যুয়াল স্টুডিওগুলিতে এটির সিডিসিএল উদাঃ ইনফিক্স স্বরলিপি: সি = এ + বি; স্ট্যাক পুশিংয়ের ডান থেকে বাম পুশিং, বি থেকে স্ট্যাক, অপারেটর, একটি স্ট্যাক করা এবং ফলস্বরূপ i, ec থেকে স্ট্যাক করা হয়। প্রাক ফিক্স নোটেশনে: = + ক্যাব এখানে সমস্ত ভেরিয়েবলগুলি 1 ম (ডান থেকে বাম) স্ট্যাকের দিকে ঠেলে দেওয়া হয় এবং তারপরে অপারেশন করা হয়। সংকলক দ্বারা বরাদ্দ করা এই মেমরিটি স্থির। সুতরাং ধরে নিই যে আমাদের অ্যাপ্লিকেশনে 1MB মেমরি বরাদ্দ করা হয়েছে, বলুন যে ব্যবহারযোগ্য ভেরিয়েবলগুলি 700kb মেমরির (সমস্ত স্থানীয় ভেরিয়েবলগুলি গতিশীলভাবে বরাদ্দ না করা হলে স্ট্যাকের দিকে ধাক্কা দেওয়া হয়) সুতরাং 3232 কেবি মেমরির গাদা বরাদ্দ করা হয়। এবং এই স্ট্যাকটির আয়ু কম হয়, যখন ফাংশনের সুযোগটি এই স্ট্যাকগুলি সাফ হয়ে যায়।

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