C / C ++ प्रोग्राम का अधिकतम स्टैक आकार


115

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

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

कृपया
विंडोज
1 पर दोनों 1) साइबर के लिए जीसीसी के लिए निर्दिष्ट करें ) यूनिक्स

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


11
आप जानते हैं कि आप पुनरावृत्ति के बिना गहराई-पहली खोज को लागू कर सकते हैं, है ना?
सेबस्टियन

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

1
मैंने अपने उत्तर में पुनरावृत्ति के बिना डीएफएस का एक छोटा सा उदाहरण दिया है
एंड्रियास ब्रिंक

56
प्लस स्टैक ओवरफ्लो के बारे में एक प्रश्न के लिए एक
सैम वाटकिंस

3
@SamWatkins हाँ, नाम स्टैक ओवरफ़्लो के साथ मेरे लिए सबसे बड़ी समस्याओं में से एक है कि मैं गूगल पर "ढेर अतिप्रवाह" को देखने और इस वेबसाइट में खत्म हो सकता है, लेकिन है जरूरी नहीं कि / कम संभावना के बारे में ढेर अतिप्रवाह ... सवाल में
lalilulelost

जवाबों:


106

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

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

यहाँ gcc के लिए डिफ़ॉल्ट स्टैक आकार के साथ एक लिंक दिया गया है।

पुनरावर्तन के बिना DFS:

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())

12
और सिर्फ संदर्भ के लिए, एक बीएफएस एक ही है सिवाय इसके कि आप एक ढेर के बजाय एक एफआईएफओ का उपयोग करते हैं।
14:17 पर स्टीव जेसोप

हां, या एसटीएल-लिंगो में एक std :: deque with pop_front / push_back
Andreas Brinck

स्टैक परिणामों के साथ आपका DFS पुनरावृत्ति संस्करण से भिन्न होगा। कुछ मामलों में यह कोई फर्क नहीं पड़ता, लेकिन दूसरों में (उदा। सामयिक प्रकार में) आपको गलत परिणाम
मिलेंगे

हां, वीएस के लिए डिफ़ॉल्ट सीमा वास्तव में 1 एमबी है। अधिक जानकारी और भिन्न मान सेट करने का तरीका Microsoft दस्तावेज़ीकरण में पाया जा सकता है: msdn.microsoft.com/en-us/library/tdkhxaks(v=vs.140).aspx
FrankS101

मैं पुनरावृत्ति के बजाय ऐसे एल्गोरिदम के लिए एक स्पष्ट स्टैक डेटा संरचना का उपयोग करना पसंद करता हूं, ताकि 1. सिस्टम स्टैक के आकार पर निर्भर न हो, 2. एक अलग डेटा संरचना का उपयोग करने के लिए एल्गोरिथ्म को बदल सकता है जैसे कतार या प्राथमिकता कतार को फेंकने के बिना। सभी कोड बाहर।
सैम वाटकिंस

47

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

  • glibc i386, x86_64 7.4 MB
  • Tru64 5.1 5.2 एमबी
  • साइगविन 1.8 एमबी
  • सोलारिस 7..10 1 एमबी
  • MacOS X 10.5 460 केबी
  • AIX 5 98 KB
  • ओपनबीएसडी 4.0 64 केबी
  • एचपी-यूएक्स 11 16 केबी

14
आनुभविक रूप से ब्रूनो हैबल लिस्ट
html/

17

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


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

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

1
यह सच है, अक्सर कर्नेल मोड में भी मामला।
DrPizza डे

6

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

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

आपको यह बताना चाहिए कि अधिक लक्षित सहायता के लिए आप किस OS और विकास परिवेश का उपयोग कर रहे हैं।

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


2
@lex: कोई सामान्य सीमा नहीं हैं। यह बहुत सारे मापदंडों पर निर्भर करता है।
माइकल फोकरिसिस

@paxdiablo: WHAT का मतलब आरक्षित और कमिटेड है?
AVD

2
आरक्षित करने के लिए आरक्षित स्थान कितना पता है, प्रतिबद्ध है कि बैकिंग स्टोरेज को कितना संलग्न करना है। दूसरे शब्दों में, पता स्थान को संग्रहीत करने का मतलब यह नहीं है कि मेमोरी तब होगी जब आपको इसकी आवश्यकता होगी। यदि आप 4K स्टैक से अधिक का उपयोग नहीं करते हैं, तो आप अन्य 1.6M के लिए वास्तविक मेमोरी बर्बाद नहीं कर रहे हैं। यदि आप गारंटी देना चाहते हैं कि पर्याप्त स्टैक होगा, आरक्षित और प्रतिबद्ध समान होना चाहिए।
पैक्सडायब्लो

2
@paxdiablo 2M - 4k 1.6M नहीं है। बस केह रहा हू। (मुझे आपकी टिप्पणी पढ़ने के पहले 3 बार भ्रमित किया गया)
ग्रिफिन

2
@griffin, kudos पहले व्यक्ति के लिए जो 3+ वर्षों में पकड़ लेता है। मैं निश्चित रूप से "बाकी का मतलब" था - मैं एक वास्तविक आंकड़ा से बचूंगा ताकि एक और संभावित गलती न हो :-)
paxdiablo

5

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

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

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

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

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


3

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

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

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