2010-06-16 7 views
5

यह कोड सरणी घोषणा के दौरान एक सेगमेंटेशन गलती उत्पन्न करता है। मैं उलझन में हूं कि ऐसा क्यों होता है। मैंने जानबूझकर 2000000000 को मूल्य के रूप में चुना क्योंकि यह 2^31 से नीचे है और एक पूर्णांक चर में फिट हो सकता है।सी प्रोग्रामिंग, यह बड़ी सरणी घोषणा एक सेगमेंटेशन गलती क्यों उत्पन्न करती है?

int main() 
{ 

    int nums_size = 2000000000; 

    int nums[nums_size]; 

    int i; 
    for(i = 0; i < nums_size; i++) { 
     nums[i] = i; 
    } 


    return 0; 

} 

उत्तर

21

ठीक है, एक बात के लिए, यह दो अरब पूर्णांक है। यदि आपके पास 32-बिट पता स्थान है और int आपके प्लेटफ़ॉर्म पर एक छोटे से बाइट्स का आकार है (32-बिट प्लेटफॉर्म के लिए विशिष्ट), तो आप उन कई पूर्णांक, अवधि को स्टोर नहीं कर सकते हैं।

अभी भी, आपके पास स्टैक पर केवल इतना स्थान उपलब्ध है, जहां स्वचालित चर स्थित हैं।

यदि आपको वास्तव में बड़ी सरणी की आवश्यकता है, तो आपको इसे malloc() का उपयोग करके डायनैमिक रूप से आवंटित करना चाहिए (और यदि आप ऐसा करते हैं, तो इसे free() का उपयोग करके इसे मुक्त करना सुनिश्चित करें!)। इस असंभव है -

+0

यदि यह मामला नहीं था, तो 32 बिट प्लेटफ़ॉर्म पर 2000000000 * 4 = 8,000,000,000 बाइट्स। यह लगभग 2^33 है, जो उपलब्ध स्मृति से अधिक है। –

+0

@ क्रिस: हाँ - मैंने पोस्ट किए जाने के बाद वास्तव में शून्य को गिनती नहीं की थी। यह बहुत सारे पूर्णांक है! –

+0

स्थिर भंडारण अवधि के साथ बहुत बड़े सरणी आवंटित करना भी आम तौर पर संभव है। – caf

4
int nums_size = 2000000000; 

int nums[nums_size]; 

ints की 2000000000 बाइट्स का मतलब यह नहीं है, यह प्रकार int की 2000000000 तत्व है, जो एक 32-बिट प्लेटफॉर्म पर मतलब है कि आप लगभग उपभोग कर रहे हैं स्मृति के 8 जीबी का मतलब है।

+0

... और ढेर पर!- Kaboom! –

3

आप ढेर पर एक विशाल सरणी आवंटित कर रहे हैं। वस्तुतः कोई सी/सी ++ कंपाइलर सही ढंग से संभाल नहीं करेगा।

आप इसे ग्लोबल्स में स्थानांतरित करने में सक्षम हो सकते हैं (जो संकलन समय पर निष्पादन योग्य में स्मृति को मैप करके स्थिर स्थान आवंटित करेगा), या malloc 'डी सरणी पर स्विच करके।

बेशक, यह अभी भी एक बार जाने के लिए स्मृति की बहुत सारी है, लेकिन कम से कम जिस तरीके से मैं उल्लेख कर रहा हूं, वह तत्काल segfault से बच जाएगा।

+1

कंपाइलर इसे सही तरीके से संभाल लेगा (अगर यह 2^32 मेमोरी आकार के अंदर था), लेकिन ऑपरेटिंग सिस्टम स्टैक को उस बड़े होने की अनुमति नहीं देगा। –

+0

न केवल सी/सी ++ बहुत सी भाषा जो स्टैक आधारित आवंटन (यानी लगभग सभी) करता है – Spudd86

0

इस संस्करण मेरे पीसी पर ठीक चलाता है:

const int nums_size = 2000000000; 
int nums[nums_size]; 

int main() 
{ 
    int i; 
    for(i = 0; i < nums_size; i++) { 
     nums[i] = i; 
    } 

    return 0; 
} 

(ठीक है, ईमानदारी से कहूं तो ठीक करते हैं यह शुरू होता है, लेकिन जल्द ही स्वैप में चला जाता है।।)

+0

और मैं अनुमान लगा रहा हूं कि आपका संस्करण 64 बिट प्लेटफॉर्म पर चलता है। अपनी 2^31 टिप्पणी से, वह निश्चित रूप से 64 बिट ओएस नहीं चला रहा है। –

+0

-1 मेरे द्वारा अधिक मेमोरी रखने के लिए (बस मजाक कर रहा है)। – cdonner

+0

@ क्रिस 2^31 टिप्पणी आपको यह नहीं बताती कि आप 32-बिट या 64-बिट चल रहे हैं या नहीं। मुझे लगता है कि जीसीसी 64-बिट प्लेटफॉर्म पर 32-बिट इन्सट्स पर डिफ़ॉल्ट है। – sigfpe

2

स्थानीय चर ढेर पर आवंटित किए जाते हैं । एप्लिकेशन को प्रदान की गई एक निश्चित राशि स्टैक स्पेस (आमतौर पर 1 एमबी -8 एमबी, ओएस के साथ बदलती है) है। सामान्य नियम बड़ी मात्रा में डेटा आवंटित करने के लिए malloc() का उपयोग करना है।

1

आपके प्रश्न का उत्तर सरल है: stackoverflow। नहीं, नहीं, साइट नहीं, बल्कि "ढेर बहने" की वास्तविक प्रक्रिया। उस सरणी को स्टोर करने के लिए आपके पास पर्याप्त stack नहीं है। इतना सरल है। स्मृति-बाधित प्रणाली पर ऐसा करना शुद्ध पागलपन है। this question भी देखें।

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