স্ট্যাকের ব্যবহার কত বেশি?


22

ইদানীং যখন আমি সি বা সি ++ লিখছি, আমি স্ট্যাকের উপরে আমার সমস্ত ভেরিয়েবলগুলি ঘোষণা করব কারণ এটি জাভা থেকে আলাদা নয় option

তবে, আমি শুনেছি যে স্ট্যাকের উপরে বড় জিনিস ঘোষণা করা খারাপ ধারণা।

  1. কেন ঠিক এই ঘটনা? আমার মতে স্ট্যাকের ওভারফ্লো জড়িত, তবে কেন হয় তা নিয়ে আমি খুব একটা পরিষ্কার নই।
  2. স্ট্যাকের স্টাফের পরিমাণ কত বেশি?

আমি স্ট্যাকের উপরে 100 এমবি ফাইল রাখার চেষ্টা করছি না, স্ট্রিং বাফার বা যা-ই হোক না কেন, মাত্র এক ডজন কিলোবাইট অ্যারে ব্যবহার করতে। এটি কি খুব বেশি স্ট্যাকের ব্যবহার?

(সদৃশ হলে সদৃশ, সন্ধানের জন্য অনুসন্ধান স্ট্যাক ওভারফ্লোতে রেফারেন্স দেয়। এমনকি একটি কল স্ট্যাক ট্যাগও নেই, আমি কেবল বিমূর্তটি ব্যবহার করেছি))


1
আপনি কীভাবে "100MB ফাইলগুলি স্ট্যাকের উপরে রাখবেন"? বাফার এবং ধারক বাস্তবায়ন (এবং স্টাড :: স্ট্রিংয়ের মতো) সাধারণত তাদের পে-লোড সঞ্চয় করতে হিপ ব্যবহার করে।
মারফি

2
পুনরাবৃত্তি জড়িত না হওয়া পর্যন্ত আপনি প্রতি ফাংশন / পদ্ধতিতে স্ট্যাকের ব্যবহারের পর্যাপ্ত পরিমাণ নিয়ে দূরে সরে যেতে পারেন, তারপরে আপনি আপনার ক্ষমতাগুলি মারাত্মকভাবে সীমাবদ্ধতার ঝুঁকিতে ফেলছেন, সুতরাং পুনরাবৃত্তির ক্রিয়াকলাপগুলির মধ্যে, আপনি সামান্য স্থানীয় হিসাবে ব্যবহার করতে চান ভেরিয়েবল / স্ট্যাক স্পেস যতটা সম্ভব।
এরিক tদ

3
লক্ষ্য করুন যে সি ও সি ++ আলাদা। একটি স্থানীয় std::vector<int>ভেরিয়েবল প্রচুর স্ট্যাক স্পেস খাবে না, বেশিরভাগ ডেটা হিটারে রয়েছে।
বেসাইল স্টারিনকিভিচ

উত্তর:


18

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

কয়েক কিলোবাইট সাধারণত ভাল থাকে। কয়েক মিলিয়ন কিলোবাইট বিপজ্জনক কারণ এটির যোগফল শুরু হয়। শত শত কিলোবাইট খুব খারাপ ধারণা।


1
টিপিক্যাল স্ট্যাকটি কি 2016 সালে আজ বেশ কয়েকটি মেগাবাইট (অর্থাত্ একাধিক, তবে সম্ভবত এক ডজনেরও কম) সীমাবদ্ধ নয় ? আমার লিনাক্স ডেস্কটপে এটি ডিফল্টরূপে 8Mbytes ...
বেসাইল স্টারিঙ্কেভিচ

"[[] লিনাক্সে, $ ulimit -aআমার সিস্টেমে অন্যগুলির মধ্যে ফিরে আসে, স্ট্যাকের জন্য আদর্শ সর্বোচ্চ আকার 1MB" হয় stack size (kbytes, -s) 8192
মার্ফি

9

একমাত্র বৈধ উত্তরটি অস্পষ্ট: "স্ট্যাক যখন উপচে পড়ে যায় তখন খুব বেশি হয়।"

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

void break_the_camels_back()
{
    int straw;
    ...
}

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

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


4

যদি আপনি স্ট্যাকের 10,000 বাইট বলার একটি অ্যারে বরাদ্দ করেন তবে সেই অ্যারেটি আকারে সীমাবদ্ধ। 10,000 অনেক বেশি হতে পারে তবে আপনার যদি 10,001 বাইটের প্রয়োজন হয় তবে আপনার প্রোগ্রামটি ক্রাশ বা খারাপ হতে পারে। সুতরাং এই পরিস্থিতিতে আপনি এমন কিছু চান যা আপনার প্রয়োজনীয় আকারের সাথে খাপ খাইয়ে নেয় এবং স্ট্যাকের মধ্যে কিছু থাকে না।

স্ট্যাকের স্ট্রিং বাফারগুলির জন্য স্থির আকারের অ্যারেগুলি কোনও সমস্যা নয় কারণ তারা স্ট্যাকটিতে স্মৃতি রাখে, এগুলি একটি সমস্যা কারণ স্থির আকারের বাফারগুলি হওয়ার জন্য অপেক্ষা করা একটি মারাত্মক সমস্যা।

তবে আপনি যদি সি ++ ব্যবহার করেন, এবং উদাহরণস্বরূপ স্ট্যাকের একটি স্টাডি :: স্ট্রিং বা একটি স্টাডি :: ভিসার ঘোষণা করেন তবে স্ট্যাকটিতে যা রয়েছে তা আসলে একটি স্থির এবং ছোট আকারের হবে। আসল ডেটা হিটে সংরক্ষণ করা হবে। আপনি স্টাডি :: স্ট্রিংয়ের ক্ষেত্রে মিলিয়ন অক্ষর সংরক্ষণ করতে পারেন এবং এটি স্ট্যাকের উপর খুব অল্প পরিমাণে ডেটা (সাধারণত 8 থেকে 24 বাইট, বাস্তবায়নের উপর নির্ভর করে) এবং স্তূপে মিলিয়ন বাইট গ্রহণ করবে।


2

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

গুরুত্বপূর্ণ বিষয় হ'ল চরের মতো স্ট্যাকের উপর কাঁচা মেমের বিশাল অংশগুলি বরাদ্দ না করা [1024 * 1024] এবং স্তূপ বরাদ্দ মোড়ানোর জন্য ক্লাসগুলি ডিজাইন করা এবং কেবলমাত্র স্বয়ংক্রিয়ভাবে বিনাশককে কল করার সুবিধার্থে স্ট্যাকটি ব্যবহার করা।

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