বড় অ্যারে মাপের উপর বিভাজন ত্রুটি


116

নিম্নলিখিত কোডটি 2 জিবি মেশিনে চালিত হওয়ার পরে আমাকে সেগমেন্টেশন ত্রুটি দেয়, তবে 4 জিবি মেশিনে কাজ করে।

int main()
{
   int c[1000000];
   cout << "done\n";
   return 0;
}

অ্যারের আকার মাত্র 4Mb। সি ++ ব্যবহার করা যেতে পারে এমন কোন অ্যারের আকারের কি সীমা আছে?

উত্তর:


130

আপনি সম্ভবত এখানে একটি স্ট্যাক ওভারফ্লো পেয়ে যাচ্ছেন। অ্যারে আপনার প্রোগ্রামের স্ট্যাক ঠিকানার জায়গায় ফিট করার জন্য খুব বড়।

যদি আপনি গাদাতে অ্যারে বরাদ্দ করেন তবে আপনার ভাল হওয়া উচিত, ধরে নিবেন আপনার মেশিনে পর্যাপ্ত স্মৃতি রয়েছে।

int* array = new int[1000000];

তবে মনে রাখবেন এটি delete[]আপনার অ্যারেতে প্রয়োজন হবে । আরও ভাল সমাধান std::vector<int>হ'ল এটি ব্যবহার করে এটি 1000000 উপাদানগুলিতে পুনরায় আকার দিন।


3
উত্তরের জন্য ধন্যবাদ, তবে আপনি আমাকে ব্যাখ্যা করতে পারেন কেন স্ট্যাকের জন্য অ্যারে বরাদ্দ করা হয় এবং কেন মূল প্রোগ্রামের মেমোরিতে নেই।
মায়াঙ্ক

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

6
সমস্ত স্বয়ংক্রিয় ভেরেবলগুলি স্ট্যাকের জন্য বরাদ্দ করা হয়। আপনি যদি ডিসেসেবলের দিকে তাকান তবে আপনি দেখতে পাবেন যে স্থানীয় ভেরিয়েবলগুলির আকার স্ট্যাক পয়েন্টার থেকে বিয়োগ করা হবে। আপনি যখন ম্যালোক বা কলোক বা মেমরি ফিক্সগুলির কোনও কল করেন fuctions যান এবং আপনার উত্তরকে সন্তুষ্ট করার জন্য পর্যাপ্ত মেমরির ব্লকগুলি খুঁজে পান।
পুনরায় চালু করুন

@ চারেলস কেন আমরা গাদা থেকে বেশি মেমরি বরাদ্দ করতে পারি? আমার বোঝাপড়া থেকে, স্ট্যাক এবং হিপ উভয়ই স্মৃতিতে বরাদ্দ করা ঠিকানার জায়গার বিপরীত দিকে চলে in
সৌরভ আগরওয়াল

2
@ সৌরভগেরওয়াল এটি একটি স্বচ্ছ স্মৃতি অঞ্চলও নয়। বরাদ্দকারী কেবল একটি ফ্রি মেমরি ব্লক ফেরত দেয় যা আপনার আকারের প্রয়োজনীয়তার সাথে খাপ খায় এবং স্ট্যাক এবং হিপগুলি কী এবং কোথায়?
ফুক্লভি

56

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

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

এটি বিএসএস বিভাগে বরাদ্দ করবে, যা হাড়ের একটি অংশ:

static int c[1000000];
int main()
{
   cout << "done\n";
   return 0;
}

এটি ডেটা বিভাগে বরাদ্দ দেবে, এটিও স্তূপের একটি অংশ:

int c[1000000] = {};
int main()
{
   cout << "done\n";
   return 0;
}

এটি গাদা কিছু অনির্দিষ্ট স্থানে বরাদ্দ হবে:

int main()
{
   int* c = new int[1000000];
   cout << "done\n";
   return 0;
}

যদি আপনি তৃতীয় প্যাটার্নটি ব্যবহার করেন তবে গাদাতে বরাদ্দ দিচ্ছেন, তবে কোনও পর্যায়ে পয়েন্টারটি [] মুছতে ভুলবেন না বা আপনি মেমরি ফাঁস করবেন। অথবা স্মার্ট পয়েন্টারগুলিতে সন্ধান করুন।
ডেভিডা

8
@ মেসোস্কাক অবশ্যই deleteআপনার যে জায়গাতে বরাদ্দ করা হয়েছে তা সর্বদা এটি ভাল অনুশীলন new। তবে আপনি যদি নিশ্চিত হন যে আপনি কেবল একবার মেমরি বরাদ্দ করেন (মূল মত) এটি কঠোরভাবে প্রয়োজন হয় না - মেমরিটি স্পষ্টভাবে ছাড়াই মূল থেকে বেরোনোর ​​সময় মুক্ত হওয়ার গ্যারান্টিযুক্ত delete
গুন্থার পাইজ

'at'drhirsch (আপনি কীভাবে একটি চরিত্রটি করবেন না?) - হ্যাঁ, নিখুঁত মন্তব্য। ওপি ভাষায় নতুন হিসাবে উপস্থিত হওয়ার সাথে সাথে আমি কেবল এটি নিশ্চিত করে তুলতে চেয়েছিলাম যে তারা এবং অন্য যে কেউ আপনার ভাল উত্তরটি দেখে, তারা যদি সাধারণত ব্যবহার করা হয় তবে তৃতীয় বিকল্পের প্রভাব সম্পর্কে অবগত ছিল।
ডেভিডা

15

এছাড়াও, আপনি যদি বেশিরভাগ ইউনিক্স এবং লিনাক্স সিস্টেমে চলমান থাকেন তবে নিম্নলিখিত কমান্ডের সাহায্যে আপনি স্ট্যাকের আকারটি অস্থায়ীভাবে বাড়িয়ে নিতে পারেন:

ulimit -s unlimited

তবে সাবধানতা অবলম্বন করুন, স্মৃতিটি একটি সীমিত সংস্থান এবং দুর্দান্ত শক্তির সাথে দুর্দান্ত দায়িত্ব আসে :)


1
এটি সমাধান তবে প্রোগ্রামের স্ট্যাক আকারে এই ডিফল্ট সীমাটি অপসারণ করার সময় আমি সবাইকে অত্যন্ত সতর্ক হওয়ার পরামর্শ দিচ্ছি। আপনি কেবল মারাত্মক পারফরম্যান্স ড্রপই পাবেন না তবে আপনার সিস্টেমটি ক্র্যাশ হতে পারে। উদাহরণস্বরূপ আমি 4 জিবি র‌্যাম সহ একটি মেশিনে কুইকোর্টের সাথে 16000 000 পূর্ণসংখ্যার উপাদানগুলির সাথে একটি অ্যারে বাছাই করার চেষ্টা করেছি এবং আমার সিস্টেমটি প্রায় নিহত হয়েছিল। LOL
rbaleksandar

@ আরবালেকসন্দর আমার মনে হয় আপনি প্রায় 16 এমবি প্রোগ্রামটি আপনার মেশিনটি মেরে ফেলেছেন কারণ আপনি অ্যারের কয়েকটি অনুলিপি (ফাংশন কল একজন হতে পারে?) আরও মেমরি সচেতন বাস্তবায়নের চেষ্টা করছেন;)
আরএসফালকন 7

আমি নিশ্চিত যে অ্যারে হ্যান্ডলিং ঠিক আছে যেহেতু আমি রেফারেন্স দিয়ে যাচ্ছি মান দিয়ে নয়। বুদবুর্গ্টের ক্ষেত্রেও একই ঘটনা ঘটে। জাহান্নাম, যদিও আমার কুইকোর্টের বাস্তবায়ন বুদবুদগুলি সফল করে তোলে এমন কিছু যা আপনি সম্ভবত ভুলভাবে প্রয়োগ করতে পারবেন না। LOL
rbaleksandar

এলএলএল আপনি রেডিক্স সাজানোর চেষ্টা করতে পারেন, বা কেবল স্টাডি :: সাজান :) ব্যবহার করতে পারেন
আরএসফালকন 7

1
কোন সম্ভাবনা নেই. এটি একটি ল্যাব অ্যাসাইনমেন্ট। : ডি
আরবেলেকসন্দর

3

আপনার অ্যারে এই ক্ষেত্রে বরাদ্দ দেওয়া হচ্ছে বরাদ্দ ব্যবহার করে একই আকারের একটি অ্যারের বরাদ্দ করার চেষ্টা করা।


3

কারণ আপনি স্ট্যাকের মধ্যে অ্যারে সঞ্চয় করেন। আপনি এটি গাদা সংরক্ষণ করা উচিত। গাদা এবং স্ট্যাকের ধারণাটি বোঝার জন্য এই লিঙ্কটি দেখুন ।

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