बड़े सरणी आकार पर विभाजन दोष


116

निम्न कोड मुझे 2Gb मशीन पर चलने पर एक विभाजन दोष देता है, लेकिन 4GB मशीन पर काम करता है।

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

सरणी का आकार सिर्फ 4Mb है। क्या किसी सरणी के आकार की सीमा है जिसका उपयोग c ++ में किया जा सकता है?

जवाबों:


130

आप शायद यहाँ केवल एक स्टैक ओवरफ़्लो प्राप्त कर रहे हैं। सरणी आपके प्रोग्राम के स्टैक एड्रेस स्पेस में फिट होने के लिए बहुत बड़ी है।

यदि आप ढेर पर सरणी आवंटित करते हैं तो आपको ठीक होना चाहिए, यह मानते हुए कि आपकी मशीन में पर्याप्त मेमोरी है।

int* array = new int[1000000];

लेकिन याद रखें कि इसके लिए आपको delete[]सरणी की आवश्यकता होगी। एक बेहतर समाधान std::vector<int>1000000 तत्वों का उपयोग करना और उनका आकार बदलना होगा।


3
उत्तर के लिए धन्यवाद, लेकिन क्या आप मुझे समझा सकते हैं कि एरे को स्टैक पर क्यों आवंटित किया गया है और मुख्य कार्यक्रम मेमोरी में क्यों नहीं।
मयंक

18
दिए गए कोड स्टैक पर आवंटित होते हैं क्योंकि यह एक सरणी के रूप में निर्दिष्ट समय पर स्थिर तत्वों की संख्या के साथ निर्दिष्ट होता है। मूल्यों को केवल मॉलोक, नए, आदि के साथ ढेर पर रखा जाता है
सेठ जॉनसन

6
सभी स्वचालित चर स्टैक पर आवंटित किए जाते हैं। यदि आप अव्यवस्था को देखते हैं तो आप स्टैक पॉइंटर से घटाए गए अपने स्थानीय चर का आकार देखेंगे। जब आप मॉलॉक या कॉलोक या मेमोरी में से किसी एक को बुलाते हैं तो नीलामी चल जाती है और मेमोरी के ब्लॉक को अपने रीकटेस्ट को संतुष्ट करने के लिए पर्याप्त पाते हैं।
फिर से चलाएं

@ हम ढेर से अधिक मेमोरी क्यों आवंटित कर सकते हैं, स्टैक से नहीं? मेरी समझ से, स्टैक और हीप दोनों मेमोरी में आवंटित एड्रेस स्पेस में विपरीत दिशा में चलते हैं।
सौरभ अग्रवाल

2
@saurabhagarwal ढेर स्थानांतरित नहीं होता है। यह एक सन्निहित स्मृति क्षेत्र भी नहीं है। आवंटनकर्ता बस एक निःशुल्क मेमोरी ब्लॉक लौटाता है जो आपके आकार की आवश्यकता को फिट करता है स्टैक और हीप क्या और कहाँ हैं?
फुलेव

56

सी या सी ++ में आमतौर पर स्थानीय वस्तुओं को स्टैक पर आवंटित किया जाता है। आप स्टैक पर एक बड़ी सरणी आवंटित कर रहे हैं, स्टैक से अधिक संभाल सकता है, इसलिए आपको स्टैकओवरफ़्लो मिल रहा है

इसे स्टैक पर स्थानीय आवंटित न करें, इसके बजाय किसी अन्य स्थान का उपयोग करें। यह या तो वस्तु को वैश्विक बनाकर या उसे वैश्विक ढेर पर आवंटित करके प्राप्त किया जा सकता है । यदि आप किसी अन्य संकलन इकाई से उपयोग नहीं करते हैं, तो वैश्विक चर ठीक हैं। यह सुनिश्चित करने के लिए कि दुर्घटना से ऐसा नहीं होता है, एक स्थिर भंडारण विनिर्देशक जोड़ें, अन्यथा बस हीप का उपयोग करें।

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

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

यह DATA सेगमेंट में आवंटित करेगा, जो ढेर का एक हिस्सा है:

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

यह ढेर में कुछ अनिर्दिष्ट स्थान पर आवंटित करेगा:

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

यदि आप तीसरे पैटर्न का उपयोग करते हैं, तो ढेर पर आवंटित करना, कुछ स्तर पर पॉइंटर को हटाना न भूलें या आप मेमोरी को लीक कर देंगे। या स्मार्ट पॉइंटर्स में देखें।
डेविडा

8
@meowsqueak बेशक यह deleteआपके साथ आवंटित हर जगह के लिए अच्छा अभ्यास है new। लेकिन अगर आपको यकीन है कि आप केवल एक बार (मुख्य रूप में) मेमोरी आवंटित करते हैं, तो इसकी कड़ाई से आवश्यकता नहीं है - मेमोरी को स्पष्ट के बिना भी मुख्य से बाहर निकलने पर मुक्त होने की गारंटी है delete
गनथर पाईज़

'at'drhirsch (आप वैसे भी एक चरित्र कैसे करते हैं?) - हाँ, उचित टिप्पणी। जैसा कि ओपी भाषा के लिए नया प्रतीत होता है, मैं सिर्फ यह सुनिश्चित करना चाहता था कि वे, और आपके अच्छे उत्तर को देखने वाले किसी और को, तीसरे विकल्प के निहितार्थों के बारे में जानते हों, जो आमतौर पर उपयोग किए जाते हैं।
davidA

15

साथ ही, यदि आप अधिकांश UNIX और Linux सिस्टम में चल रहे हैं, तो आप निम्न कमांड द्वारा स्टैक का आकार अस्थायी रूप से बढ़ा सकते हैं:

ulimit -s unlimited

लेकिन सावधान रहें, स्मृति एक सीमित संसाधन है और बड़ी शक्ति के साथ महान जिम्मेदारियां आती हैं :)


1
यह समाधान है लेकिन मैं प्रोग्राम के स्टैक आकार पर इस डिफ़ॉल्ट सीमा को हटाते समय सभी को बेहद सतर्क रहने की सलाह देता हूं। आप न केवल गंभीर प्रदर्शन ड्रॉप का अनुभव करेंगे, बल्कि आपका सिस्टम क्रैश हो सकता है। उदाहरण के लिए मैंने 4GB रैम वाली मशीन पर क्विकॉर्ट के साथ 16 000 000 पूर्णांक तत्वों के साथ एक सरणी को सॉर्ट करने की कोशिश की और मेरा सिस्टम लगभग मारा गया। LOL
rbaleksandar

@rbaleksandar मुझे लगता है कि आप ~ 16 एमबी कार्यक्रम लगभग अपनी मशीन को मार देते हैं क्योंकि आप सरणी की कई प्रतियों के साथ काम कर रहे थे (एक प्रति फ़ंक्शन कॉल हो सकता है?) अधिक स्मृति जागरूक कार्यान्वयन का प्रयास करें?)
RSFalcon7

मुझे पूरा यकीन है कि सरणी हैंडलिंग ठीक है क्योंकि मैं संदर्भ से गुजर रहा हूं और मूल्य से नहीं। बुलबुले के साथ भी यही होता है। नरक, भले ही एस्कॉर्ट के मेरे कार्यान्वयन ने बुलबुले को बेकार कर दिया, जो कि आप संभवतः गलत तरीके से लागू नहीं कर सकते हैं। LOL
rbaleksandar 10

LOL आप रेडिक्स के प्रकार की कोशिश कर सकते हैं, या बस std :: सॉर्ट का उपयोग कर सकते हैं :)
RSFalcon7

1
सवाल ही नहीं। यह एक लैब असाइनमेंट है। : D
rbaleksandar

3

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


3

क्योंकि आप सरणी को स्टैक में संग्रहीत करते हैं। आपको इसे ढेर में संग्रहीत करना चाहिए। ढेर और ढेर की अवधारणा को समझने के लिए इस लिंक को देखें ।

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