ढेर की सीमा


10

हाल ही में मैंने अलग-अलग OS के साथ तीन उपकरणों पर एक स्टैक की सीमा का परीक्षण किया है (सीमा से, मेरा मतलब है कि स्टैक हो सकते हैं अधिकतम स्तर), और मैंने देखा कि हर बार जब मैंने 2 ^ 16 का स्तर मारा तो यह मुझे देता है अतिप्रवाह त्रुटि, और जब मैंने 2 ^ 16-1 डाला तो यह ठीक से काम करता है।

तो मेरा सवाल है - क्या यह सच है? क्या स्टैक की परिभाषा द्वारा अधिकतम सीमा 2 ^ 16-1 है या यह OS पर निर्भर करता है?


5
here i mean by limit the maximum number of levels that can the stack haveएक स्तर क्या है?
tkausl 13


3
आप इसे कैसे परख रहे हैं? क्या आप इनपुट के रूप में 2-बाइट (डॉर्ड) का उपयोग कर रहे हैं?
pro3carp3

6
आप किस प्रोग्रामिंग लैंग्वेज का उपयोग कर रहे हैं? एक निश्चित संख्या पर इस तरह की तीव्र सीमा इंगित करती है कि यह आपकी भाषा के विशिष्ट रनटाइम द्वारा एक जानबूझकर सीमा है और ओएस द्वारा आवंटित स्टैक आकार से नहीं। उदाहरण के लिए अजगर आपको वास्तविक स्टैक ओवरफ्लो से टकराने से रोकने के लिए डिफ़ॉल्ट रूप से 1000 की सीमा लागू करता प्रतीत होता है (वास्तविक स्टैक ओवरफ्लो से
उबरना

जवाबों:


20

यह दृढ़ता से ऑपरेटिंग सिस्टम विशिष्ट (और कंप्यूटर विशिष्ट) है और कुछ ओएस पर आपके पास सीमा को कॉन्फ़िगर करने (और यहां तक ​​कि) बढ़ाने के कुछ तरीके हैं। यह भी संकलक विशिष्ट (या आपकी प्रोग्रामिंग-भाषा-कार्यान्वयन विशिष्ट) है, क्योंकि कुछ संकलक ( कुछ सीमित प्रकार के सी कोड के लिए हाल के जीसीसी सहित ) कुछ पूंछ कॉल का अनुकूलन करने में सक्षम हैं

(कुछ प्रोग्रामिंग भाषा विनिर्देशों के लिए टेल कॉल ऑप्टिमाइज़ेशन की आवश्यकता होती है , जैसे R5RS )

मुझे यकीन नहीं है कि आपका सवाल समझ में आता है (और निश्चित रूप से आपकी 2 16 की सीमा नहीं)। मेरे लिनक्स डेस्कटॉप (डेबियन / सिड / x86-64, लिनक्स 4.9 कर्नेल, 32 जीबी रैम, इंटेल i5-4690S) पर, मेरे पास 8 मेगाबाइट तक का कॉल स्टैक हो सकता है (और मैं उस सीमा को बढ़ा सकता हूं, अगर मैं वास्तव में चाहता था। )।

मल्टी-थ्रेडिंग और एएसएलआर आपके प्रश्न को और अधिक जटिल बना रहे हैं । उदाहरण देखें pthread_attr_setstack (3)विभाजन के ढेर के बारे में भी पढ़ें (अक्सर गो कार्यान्वयन द्वारा उपयोग किया जाता है ) और निरंतरता शैली के बारे में । इस उत्तर को भी देखें ।

इसके लायक क्या है, मैंने सिर्फ निम्नलिखित C99 (और C11) कोड की भी कोशिश की:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void recfun(int x, int d) {
  printf("start recfun x=%d d=%d\n", x, d);
  fflush(NULL);
  if (d>0)
    recfun(x+1, d-1);
  printf("end recfun x=%d d=%d\n", x, d);
}

int main(int argc, char**argv) {
  int md = argc>1?atoi(argv[1]):10000;
  printf ("start md=%d\n", md);
  recfun(0, md);
  printf("end md=%d clock=%ld µs\n", md, clock());
}    
// eof recur.c

और मैं उस recurकार्यक्रम को चलाने में सक्षम था (जैसा कि जीसीसी 6 के साथ संकलित किया गया gcc -Wall -O recur.c -o recur) recur 161000 (आपकी 2 16 की सीमा से अधिक)। इसके साथ recur 256000ही काम भी किया। इसके साथ recur 456000दुर्घटनाग्रस्त हो गया ( स्तर के लिए एक ढेर अतिप्रवाह के साथ x=272057)। मेरे पास अन्य परीक्षणों के लिए धैर्य नहीं है। अपने कंप्यूटर पर कोशिश करें। अनुकूलन के लिए पूछना मत भूलना।

अंगूठे का एक नियम (डेस्कटॉप, लैपटॉप, टैबलेट के लिए) आपके कॉल स्टैक को एक मेगाबाइट से नीचे रखने के लिए हो सकता है।

भी पास करके -fstack-usage करने के लिए gcc मैं निम्नलिखित हो रही recur.suफ़ाइल (संख्या, मेरे 8Mb ढेर सीमा अंतर्ज्ञान के साथ संगत बाइट्स में हैं, मत भूलना mainकॉल फ्रेम, और अधिक महत्वपूर्ण प्रारंभिक ढेर लेआउट, कर्नेल द्वारा स्थापित जब कर execve (2 ) ..., crt0 के लिए ):

 recur.c:5:10:recfun    32  static
 recur.c:13:9:main  16  static

पुनश्च। मेरे Arduino में केवल 2kbytes RAM के साथ एक Atmega328 है , इसलिए निश्चित रूप से वह इतना पुनरावृत्ति नहीं कर सकता है। मुझे लगता है कि केवल कुछ सैकड़ों स्टैक फ्रेम Arduinos पर व्यावहारिक रूप से संभव हैं।


3

प्रक्रिया के मुख्य धागे के लिए स्टैक का आकार विंडोज लिंकर द्वारा सेट किया गया है। डिफ़ॉल्ट 1MB है, लेकिन / STACK स्विच के साथ समायोजित किया जा सकता है। बाद में बनाए गए थ्रेड CreateThread फ़ंक्शन के dwStackSize पैरामीटर का उपयोग कर सकते हैं।

इसलिए .. यदि आप विभिन्न विंडोज ओएस का परीक्षण कर रहे हैं, तो कम से कम NT4.0 के बाद से वे सभी एक ही डिफ़ॉल्ट स्टैक आकार में हैं।

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