2009-12-01 18 views
75

मैं 100 एक्स 100 सरणी पर डीएफएस करना चाहता हूं। (सरणी के तत्व ग्राफ नोड्स का प्रतिनिधित्व करते हैं) तो सबसे खराब मामला मानते हुए, रिकर्सिव फ़ंक्शन कॉल की गहराई 10000 तक जा सकती है जिसमें प्रत्येक कॉल 20 बाइट्स तक ले जाती है। तो क्या यह संभव है कि स्टैक ओवरफ्लो की संभावना है?सी/सी ++ प्रोग्राम का अधिकतम ढेर आकार

सी/सी ++ में अधिकतम आकार का ढेर क्या है?

विंडोज
2) यूनिक्स पर दोनों
1) cygwin के लिए जीसीसी के लिए निर्दिष्ट करें

सामान्य सीमा क्या हैं?

+8

आप जानते हैं कि आप बिना किसी घुसपैठ के गहराई से पहली खोज को कार्यान्वित कर सकते हैं, है ना? – Sebastian

+1

नहीं, मुझे नहीं पता, कृपया समझाएं। – avd

+0

मैंने वास्तविक उत्तर स्टैक ओवरफ़्लो –

उत्तर

73

विजुअल स्टूडियो में डिफ़ॉल्ट स्टैक आकार 1 एमबी है, मुझे लगता है कि 10,000 स्टैक फ्रेम की रिकर्सन गहराई के साथ अधिकतम ~ 100 बाइट्स हो सकते हैं जो डीएफएस एल्गोरिदम के लिए पर्याप्त होना चाहिए।

विजुअल स्टूडियो समेत अधिकांश कंपाइलर्स आपको स्टैक आकार निर्दिष्ट करने देते हैं। कुछ (सभी?) लिनक्स स्वाद पर स्टेक आकार निष्पादन योग्य का हिस्सा नहीं है लेकिन ओएस में एक पर्यावरण चर है। फिर आप ulimit -s के साथ स्टैक आकार की जांच कर सकते हैं और इसे ulimit -s 16384 उदाहरण के साथ एक नए मान पर सेट कर सकते हैं।

यहां जीसी के लिए डिफ़ॉल्ट स्टैक आकार के साथ link है। प्रत्यावर्तन के बिना

डीएफएस: धागे के लिए

std::stack<Node> dfs; 
dfs.push(start); 
do { 
    Node top = dfs.top(); 
    if (top is what we are looking for) { 
     break; 
    } 
    dfs.pop(); 
    for (outgoing nodes from top) { 
     dfs.push(outgoing node); 
    } 
} while (!dfs.empty()) 
+0

Thnk u बहुत अधिक – avd

+7

और केवल संदर्भ के लिए, एक बीएफएस वही है जो आप एक फीफो का उपयोग करते हैं एक ढेर के बजाय। –

+0

हां, या एसटीएल-लिंगो में एक std :: डेक का उपयोग pop_front/push_back –

11

प्लेटफार्म-निर्भर, टूलचेन-निर्भर, उलिम-निर्भर, पैरामीटर-निर्भर .... यह बिल्कुल निर्दिष्ट नहीं है, और कई स्थिर और गतिशील गुण हैं जो इसे प्रभावित कर सकते हैं।

+0

के बारे में एक प्रश्न के लिए मेरे उत्तर – avd

+4

कोई "सामान्य सीमाएं" नहीं हैं। विंडोज़ पर, डिफ़ॉल्ट वीसी ++ लिंकर विकल्प और डिफ़ॉल्ट CreateThread व्यवहार के साथ, आमतौर पर प्रति थ्रेड लगभग 1 एमआईबी कुछ। असीमित उपयोगकर्ता के साथ, लिनक्स पर, मेरा मानना ​​है कि आम तौर पर कोई सीमा नहीं है (ढेर लगभग पूरी पता स्थान पर कब्जा करने के लिए नीचे की ओर बढ़ सकता है)। असल में, अगर आपको पूछना है, तो आपको ढेर का उपयोग नहीं करना चाहिए। – DrPizza

+1

एम्बेडेड सिस्टम पर, आपके पास 4k या उससे कम हो सकता है। उस स्थिति में आपको तब भी पूछना पड़ता है जब स्टैक का उपयोग करना उचित होता है। जवाब आमतौर पर एक गैलिक शग है। –

3

हां, स्टैक ओवरफ़्लो की संभावना है। सी और सी ++ मानक स्टैक गहराई जैसी चीज़ों को निर्देशित नहीं करते हैं, वे आम तौर पर एक पर्यावरणीय मुद्दा हैं।

सबसे सभ्य विकास वातावरण और/या ऑपरेटिंग सिस्टम आपको लिंक या लोड समय पर, प्रक्रिया के ढेर आकार को तैयार करने देंगे।

आपको यह निर्दिष्ट करना चाहिए कि आप किस ओएस और विकास पर्यावरण का उपयोग अधिक लक्षित सहायता के लिए कर रहे हैं।

उदाहरण के लिए, उबंटू कर्मिक कोआला के तहत, जीसीसी के लिए डिफ़ॉल्ट 2 एम आरक्षित और 4 के प्रतिबद्ध है लेकिन जब आप प्रोग्राम को लिंक करते हैं तो इसे बदला जा सकता है। ऐसा करने के लिए ld के --stack विकल्प का उपयोग करें।

+0

सामान्य सीमाएं क्या हैं? – avd

+2

@lex: कोई सामान्य सीमा नहीं है। यह कई मानकों पर निर्भर करता है। –

+0

@paxdiablo: आरक्षित और प्रतिबद्ध का अर्थ क्या है? – avd

31

ढेर अक्सर छोटे होते हैं। आप लिंक समय पर डिफ़ॉल्ट बदल सकते हैं, या रन टाइम पर भी बदल सकते हैं। संदर्भ के लिए कुछ चूक कर रहे हैं:

  • glibc i386, x86_64 7.4 एमबी
  • Tru64 5.1 5.2 एमबी
  • Cygwin 1.8 एमबी
  • सोलारिस 7..10 1 एमबी
  • MacOS X 10.5 460 KB
  • एईक्स 5 98 केबी
  • ओपनबीएसडी 4।0 64 KB
  • HP-UX 11 16 KB
+4

इस जानकारी पर कोई संदर्भ? –

+8

ब्रूनो हाइबल द्वारा अनुभवी निर्धारित http://lists.gnu.org/archive/html/bug-coreutils/2009-10/msg00262.html – pixelbeat

2

मुझे यकीन है कि आप एक आयताकार सरणी पर गहराई पहले खोज करके क्या मतलब है नहीं कर रहा हूँ, लेकिन मैं आपको पता है कि तुम क्या कर रहे हैं मान।

यदि स्टैक सीमा एक समस्या है तो आप अपने पुनरावर्ती समाधान को एक पुनरावर्तक समाधान में परिवर्तित करने में सक्षम होना चाहिए जो ढेर से आवंटित एक स्टैक पर मध्यवर्ती मूल्यों को धक्का देता है।

1

मैं बस काम पर ढेर से बाहर भाग गया, यह एक डेटाबेस था और यह कुछ धागे चला रहा था, मूल रूप से पिछले डेवलपर ने ढेर पर एक बड़ी सरणी फेंक दी थी, और ढेर वैसे भी कम था। सॉफ़्टवेयर को माइक्रोसॉफ्ट विजुअल स्टूडियो 2015 का उपयोग करके संकलित किया गया था।

भले ही थ्रेड स्टैक से बाहर हो गया हो, फिर भी यह चुपचाप असफल रहा और जारी रहा, यह केवल स्टैक पर डेटा की सामग्री तक पहुंचने के लिए ढेर हो गया।

सबसे अच्छी सलाह जो मैं दे सकता हूं वह है कि ढेर पर सरणी घोषित न करें - खासकर जटिल अनुप्रयोगों और विशेष रूप से धागे में, इसके बजाय ढेर का उपयोग करें। यही वह है जो इसके लिए है;)

यह भी ध्यान रखें कि स्टैक घोषित करते समय तुरंत विफल नहीं हो सकता है, लेकिन केवल पहुंच पर। मेरा अनुमान है कि संकलक खिड़कियों के नीचे "आशावादी रूप से" स्टैक घोषित करता है, यानी यह मान लेगा कि ढेर घोषित कर दिया गया है और इसका उपयोग करने के लिए पर्याप्त रूप से आकार दिया गया है और फिर पता चला है कि ढेर वहां नहीं है।

विभिन्न ऑपरेटिंग सिस्टम में अलग-अलग स्टैक घोषणा नीतियां हो सकती हैं। यदि आप जानते हैं कि ये नीतियां क्या हैं, तो कृपया एक टिप्पणी छोड़ दें।

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