2009-11-01 13 views
5

क्या आप सी ++ में स्टैक ओवरफ़्लो का उदाहरण दे सकते हैं? रिकर्सिव केस के अलावा:क्या आप सी ++ में स्टैक ओवरफ़्लो का उदाहरण दे सकते हैं?

void foo() { foo(); } 
+11

तुम मुझे मेरा उत्तर में C++ पूरे stackoverflow वेबसाइट को लागू करना चाहते हैं? वाह ... :) – dicroce

+0

@dicroce: lol +1 :-) –

+0

अनंत रिकर्सन स्वीकार्य उत्तर क्यों नहीं है? – outis

उत्तर

14

सामान्य मामला जिसमें अनंत रिकर्सन शामिल नहीं है, वह स्टैक पर एक स्वचालित चर घोषित कर रहा है जो बहुत बड़ा है। उदाहरण के लिए:

int foo() 
{ 
    int array[1000000]; 

} 
11

कृपया Stack overflow - Wikipedia देखें। मैंने सीधे उदाहरण अनुभाग से लिंक किया है।

6
void function() 
{ 
function(); 
} 
+1

+1 स्वच्छ और सीधा। यह सब आपको ढेर को उड़ाने की जरूरत है। –

+1

क्या हम इसे कम कर सकते हैं? हाँ हम कर सकते हैं! 'शून्य _() {_();}' ... यह लगभग पर्ल की तरह है;) – Thomas

+1

अंतर, पर्ल भूमि में, यह संभावना है कि आप पर्ल से पहले * अपने * ढेर को उड़ा देंगे। – Rob

1

यह उदाहरण अनियंत्रित रिकर्सन दिखाता है। अंत में, ढेर इस प्रक्रिया को पूरी तरह से बार और सेवानिवृत्त के उदाहरण द्वारा ओवरराइट किया जाएगा करने के लिए आवंटित स्थान दिया गया है ...

int foo(int bar) 
{ 
    int ret = foo(42); 
    return ret; 
} 
3

रखें मुख्य वापस जाने के लिए जब तक ढेर बाहर चलाता है की कोशिश कर रहा?

int main(int argc, char **argv) 
{ 
    return main(argc, argv); 
} 
+3

मुख्य कॉल करना कानूनी नहीं है() सी ++ में। – Tmdean

+0

मुझे पता है कि यह सही तरीके से प्रारूपित नहीं होगा, लेकिन इस उचित कार्यक्रम के लिए '-Wall' के साथ कोई चेतावनी नहीं है: int main(int argc, char **argv) { if (argc == 0){return 0;} else {std::cout << argc << std::endl; return main(0, argv);} }

+0

मेरा मतलब यह अजीब बात है कि' g ++ 'मुख्य कॉल करते समय कोई चेतावनी नहीं देता है; आप वास्तव में सही हैं (मैंने जो देखा है) से मानक मानक 'मुख्य' को कॉल करने की अनुमति देता है। –

0

अनंत प्रत्यावर्तन:

 
void infiniteFunction() 
{ 
    infiniteFunction(); 
} 

int main() 
{ 
    infiniteFunction(); 
    return 0; 
} 
5

यहाँ एक है कि व्यवहार में हो सकता है:

int factorial(int x) { 
    return x == 0 ? 1 : x * factorial(x-1); 
} 

यह नकारात्मक x के लिए ढेर overflows। और, as Frank Krueger mentioned, बहुत बड़े x के लिए भी (लेकिन फिर int पहले ओवरफ़्लो होगा)।

3

प्रति संपादित के रूप में :-)

void ping() 
{ 
    pong(); 
} 

void pong() 
{ 
ping(); 
} 

इसके अलावा, मेरा मानना ​​है कि यदि आप अधिकतम धागा ढेर आकार (वी.एस. में डिफ़ॉल्ट रूप से 1MB) की तुलना में अधिक स्थान आवंटित करने के लिए प्रयास करते समय आपको ढेर अतिप्रवाह प्राप्त कर सकते हैं, तो int a[100000]; कुछ की तरह अपवाद प्रदान करना चाहिए।

+0

उन्हें पिंग कहते हैं और पोंग लॉल अच्छा एक –

+0

हाँ, एक विनोदी नाम! –

2

मुझे विश्वास नहीं है कि हमने हर समय का सबसे बड़ा रिकर्सन उदाहरण छोड़ दिया है, फैक्टोरियल!

#include <stdio.h> 

double fact(double n) { 
    if (n <= 0) return 1; 
    else return n * fact(n - 1); 
} 

int main() { 
    printf("fact(5) = %g\n", fact(5)); 
    printf("fact(10) = %g\n", fact(10)); 
    printf("fact(100) = %g\n", fact(100)); 
    printf("fact(1000) = %g\n", fact(1000)); 
    printf("fact(1000000) = %g\n", fact(1000000)); 
} 

जीसीसी 4.0.1 के साथ ओएस एक्स 10.5.8 पर:

$ gcc f.c -o f && ./f 
fact(5) = 120 
fact(10) = 3.6288e+06 
fact(100) = 9.33262e+157 
fact(1000) = inf 
Segmentation fault 

दुर्भाग्य से, ओएस एक्स के लिए एक "ढेर अतिप्रवाह" के एक "विभाजन गलती" के बजाय रिपोर्ट। बहुत बुरा।

0

यदि आप बड़े ऑब्जेक्ट को स्टैक (बाय-वैल्यू) पर रखने की कोशिश करते हैं तो आप एक स्टैक ओवरफ़्लो भी प्राप्त कर सकते हैं।

1

आप समारोह से एक ढेर अतिप्रवाह में परिणाम की एक स्पष्ट गैर पुनरावर्ती कार्यक्रम जनरेट करना चाहते हैं कॉल:

#!/usr/bin/env python 
import sys 

print "void func" + sys.argv[1] + "() { }" 
for i in xrange(int(sys.argv[1])-1, -1, -1): 
    print "void func" + str(i) + "() { func" + str(i+1) + "(); }" 
print "int main() { func0(); return 0; }" 

नमूना उत्पादन:

$ python recursion.py 5 
void func5() { } 
void func4() { func5(); } 
void func3() { func4(); } 
void func2() { func3(); } 
void func1() { func2(); } 
void func0() { func1(); } 
int main() { func0(); return 0; } 

नमूना उपयोग:

$ python recursion.py 250000 | g++ -x c++ - && ./a.out 

कम से कम मेरे सिस्टम पर, कॉल स्टैक एस 174602 होने लगता है, इसलिए आपको उस से बड़ा होने के लिए recursion.py पर तर्क सेट करने की आवश्यकता होगी; और प्रोग्राम को संकलित और लिंक करने में कुछ मिनट लगते हैं।

3

संकलन समय उदाहरण:

template <int N> 
struct Factorial { 
    enum { value = N * Factorial<N - 1>::value }; 
}; 

// ... 
{ 
    int overflow = Factorial<10>::value; 
} 
संबंधित मुद्दे