2009-12-04 15 views
79

2 जीबी मशीन पर चलने पर निम्न कोड मुझे सेगमेंटेशन गलती देता है, लेकिन 4 जीबी मशीन पर काम करता है।बड़े सरणी आकारों पर सेगमेंटेशन गलती

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

सरणी का आकार केवल 4 एमबी है। क्या सरणी के आकार पर कोई सीमा है जिसका उपयोग सी ++ में किया जा सकता है?

उत्तर

93

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

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

int* array = new int[1000000];

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

+0

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

+9

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

+3

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

2

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

46

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

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

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

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; 
} 
+0

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

+6

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

+0

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

2

क्योंकि आप स्टेशन में सरणी की दुकान सी.के.। आपको इसे ढेर में स्टोर करना चाहिए। ढेर और ढेर की अवधारणा को समझने के लिए this link देखें।

6

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

ulimit -s unlimited 

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

+0

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

+0

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

+0

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

संबंधित मुद्दे