एक StackOverflowError क्या है?


439

क्या है StackOverflowError, इसके कारण क्या हैं, और मुझे उनसे कैसे निपटना चाहिए?


जावा में स्टैक का आकार छोटा है। और कुछ बार जैसे कई पुनरावर्ती कॉल आपको इस समस्या का सामना करते हैं। आप लूप द्वारा अपने कोड को फिर से डिज़ाइन कर सकते हैं। आप इस url में इसे करने के लिए सामान्य डिज़ाइन पैटर्न पा सकते हैं: jndanial.com/73
JNDanial

इसे प्राप्त करने का एक गैर-स्पष्ट तरीका: new Object() {{getClass().newInstance();}};कुछ स्थैतिक संदर्भ (जैसे mainविधि) में लाइन जोड़ें । उदाहरण के संदर्भ से काम नहीं करता है (केवल फेंकता है InstantiationException)।
जॉन मैक्लेन ने

जवाबों:


408

पैरामीटर और स्थानीय चर स्टैक पर आवंटित किए जाते हैं (संदर्भ प्रकारों के साथ, ऑब्जेक्ट हीप पर रहता है और स्टैक संदर्भों में एक वैरिएबल जो कि हीप पर ऑब्जेक्ट होता है)। स्टैक आमतौर पर आपके पते के स्थान के ऊपरी छोर पर रहता है और जैसा कि इसका उपयोग किया जाता है यह पता स्थान के नीचे (यानी शून्य की ओर) होता है।

आपकी प्रक्रिया में एक ढेर भी होता है , जो आपकी प्रक्रिया के निचले सिरे पर रहता है। जैसे ही आप मेमोरी आवंटित करते हैं, यह हीप आपके एड्रेस स्पेस के ऊपरी छोर की तरफ बढ़ सकता है। जैसा कि आप देख सकते हैं, ढेर के साथ "टकराने" के लिए ढेर की संभावना है (टेक्टोनिक प्लेट की तरह थोड़ा सा !!!)।

स्टैक ओवरफ्लो का सामान्य कारण एक खराब पुनरावर्ती कॉल है । आमतौर पर, यह तब होता है जब आपके पुनरावर्ती कार्यों में सही समाप्ति की स्थिति नहीं होती है, इसलिए यह हमेशा के लिए खुद को समाप्त कर देता है। या जब समाप्ति की स्थिति ठीक है, तो इसे पूरा करने से पहले बहुत अधिक पुनरावर्ती कॉल की आवश्यकता हो सकती है।

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

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

यदि आपको कोई स्पष्ट पुनरावर्ती कार्य नहीं मिला है, तो यह देखने के लिए जांचें कि क्या आप किसी भी पुस्तकालय के कार्यों को बुला रहे हैं, जो अप्रत्यक्ष रूप से आपके फ़ंक्शन को बुलाया जाएगा (जैसे ऊपर अंतर्निहित मामला)।


1
मूल पोस्टर: अरे यह बहुत अच्छा है। तो स्टैक ओवरफ्लो के लिए रिकर्सन हमेशा जिम्मेदार होता है? या अन्य चीजें भी उनके लिए जिम्मेदार हो सकती हैं? दुर्भाग्य से मैं एक पुस्तकालय का उपयोग कर रहा हूं ... लेकिन ऐसा नहीं जिसे मैं समझता हूं।
जिग्गी

4
हा हा हा, तो यहाँ यह है: जबकि (अंक <100) {addMouseListeners (); moveball (); checkforcollision (); ठहराव (गति);} वाह क्या मुझे लगता है कि मैं माउस श्रोताओं के ढेर के साथ खत्म नहीं होगा के लिए लंगड़ा लगता है ... धन्यवाद दोस्तों!
जिग्गी

4
यदि आप इस पर विकिपीडिया लेख को en.wikipedia.org/wiki/Stack_overflow पर देखते हैं, तो स्टैक ओवरफ्लो भी स्टैक पर आबंटित होने के लिए बहुत बड़ा नहीं हो सकता है ।
जेबी किंग

8
यह बताया जाना चाहिए कि स्टैक ओवरफ्लो त्रुटि को "हैंडल" करना लगभग असंभव है। अधिकांश वातावरणों में, त्रुटि को संभालने के लिए किसी को स्टैक पर कोड चलाने की आवश्यकता होती है, जो कि अधिक स्टैक स्थान नहीं होने पर मुश्किल है।
हॉट लाइक्स

3
@ जेबी किंग: वास्तव में जावा पर लागू नहीं होता है, जहां केवल आदिम प्रकार और संदर्भ स्टैक पर रखे जाते हैं। सभी बड़ा सामान (सरणियां और ऑब्जेक्ट) ढेर पर है।
jcsahnwaldt का कहना है कि GoFundMonica

107

इसका वर्णन करने के लिए, पहले हमें यह समझना चाहिए कि स्थानीय चर और वस्तुएं कैसे संग्रहीत की जाती हैं।

स्थानीय चर में जमा हो जाती ढेर : यहां छवि विवरण दर्ज करें

यदि आपने छवि को देखा तो आपको यह समझने में सक्षम होना चाहिए कि चीजें कैसे काम कर रही हैं।

जब एक फ़ंक्शन कॉल जावा एप्लिकेशन द्वारा मंगाई जाती है, तो कॉल स्टैक पर स्टैक फ्रेम आवंटित किया जाता है। स्टैक फ्रेम में शामिल विधि के पैरामीटर, इसके स्थानीय पैरामीटर और विधि का वापसी पता शामिल है। वापसी का पता निष्पादन बिंदु को दर्शाता है, जिसमें से लागू होने के बाद प्रोग्राम निष्पादन जारी रहेगा। यदि नए स्टैक फ्रेम के लिए कोई स्थान नहीं है, तो StackOverflowErrorजावा वर्चुअल मशीन (जेवीएम) द्वारा फेंक दिया जाता है।

सबसे आम मामला जो संभवतः जावा एप्लिकेशन के ढेर को समाप्त कर सकता है, वह पुनरावृत्ति है। पुनरावृत्ति में, एक विधि अपने निष्पादन के दौरान खुद को आमंत्रित करती है। रिकर्सियन को एक शक्तिशाली सामान्य-प्रयोजन प्रोग्रामिंग तकनीक के रूप में माना जाता है, लेकिन इससे बचने के लिए सावधानी के साथ उपयोग किया जाना चाहिएStackOverflowError

StackOverflowErrorनीचे फेंकने का एक उदाहरण नीचे दिखाया गया है:

StackOverflowErrorExample.java:

public class StackOverflowErrorExample {

  public static void recursivePrint(int num) {
    System.out.println("Number: " + num);

    if (num == 0)
      return;
    else
      recursivePrint(++num);
  }

  public static void main(String[] args) {
    StackOverflowErrorExample.recursivePrint(1);
  }
}

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

एक नमूना निष्पादन, -Xss1M1 एमबी के बराबर थ्रेड स्टैक के आकार को निर्दिष्ट करने वाले ध्वज का उपयोग करके नीचे दिखाया गया है:

Number: 1
Number: 2
Number: 3
...
Number: 6262
Number: 6263
Number: 6264
Number: 6265
Number: 6266
Exception in thread "main" java.lang.StackOverflowError
        at java.io.PrintStream.write(PrintStream.java:480)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
        at java.io.PrintStream.write(PrintStream.java:527)
        at java.io.PrintStream.print(PrintStream.java:669)
        at java.io.PrintStream.println(PrintStream.java:806)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        ...

जेवीएम के प्रारंभिक कॉन्फ़िगरेशन के आधार पर, परिणाम भिन्न हो सकते हैं, लेकिन अंततः StackOverflowErrorफेंक दिया जाएगा। यह उदाहरण एक बहुत अच्छा उदाहरण है कि कैसे पुनरावृत्ति समस्याओं का कारण बन सकती है, यदि सावधानी के साथ लागू नहीं किया गया है।

StackOverflowError से कैसे निपटें

  1. सबसे सरल समाधान स्टैक ट्रेस का सावधानीपूर्वक निरीक्षण करना और रेखा संख्याओं के दोहराव पैटर्न का पता लगाना है। ये पंक्ति संख्या कोड को पुनरावृत्ति कहे जाने का संकेत देती है। एक बार जब आप इन पंक्तियों का पता लगा लेते हैं, तो आपको अपने कोड का सावधानीपूर्वक निरीक्षण करना चाहिए और समझना चाहिए कि पुनरावृत्ति कभी समाप्त क्यों नहीं होती है।

  2. यदि आपने सत्यापित किया है कि पुनरावृत्ति को सही तरीके से लागू किया गया है, तो आप बड़ी संख्या में इनवोकेशन की अनुमति देने के लिए, स्टैक का आकार बढ़ा सकते हैं। स्थापित जावा वर्चुअल मशीन (JVM) के आधार पर, डिफ़ॉल्ट थ्रेड स्टैक आकार 512KB, या 1MB के बराबर हो सकता है । आप -Xssध्वज का उपयोग करके थ्रेड स्टैक का आकार बढ़ा सकते हैं । यह ध्वज या तो प्रोजेक्ट के कॉन्फ़िगरेशन के माध्यम से, या कमांड लाइन के माध्यम से निर्दिष्ट किया जा सकता है। -Xssतर्क का प्रारूप है: -Xss<size>[g|G|m|M|k|K]


कुछ जावा संस्करणों में एक बग प्रतीत होता है जब विंडोज़ का उपयोग करते हुए -Xss तर्क केवल नए थ्रेड पर प्रभावी होता है
goerlibe

65

यदि आप एक समारोह की तरह है:

int foo()
{
    // more stuff
    foo();
}

फिर foo () अपने आप को कॉल करता रहेगा, गहरी और गहरी हो रही होगी, और जब अंतरिक्ष आपके द्वारा भरे जाने वाले कार्यों का ट्रैक रखता है, तो आपको स्टैक ओवरफ्लो त्रुटि मिलती है।


12
गलत। आपका कार्य पूंछ-पुनरावर्ती है। अधिकांश संकलित भाषाओं में पूंछ-पुनरावृत्ति अनुकूलन है। इसका मतलब यह है कि पुनरावृत्ति एक साधारण लूप में कम हो जाती है और आप कुछ सिस्टम पर कोड के इस टुकड़े के साथ ढेर अतिप्रवाह को कभी नहीं मारेंगे।
Cheery

Cheery, जो गैर-कार्यात्मक भाषाएं पूंछ की पुनरावृत्ति का समर्थन करती हैं?
घोड़ागुए

@ बहन और जावास्क्रिप्ट के कुछ कार्यान्वयन
पचेरियर

@horseyguy Scala को टेल रिकर्सन के लिए सपोर्ट है।
अजीत के कागर

यह एक ढेर अतिप्रवाह बना सकता है का सार कैप्चर करता है। अच्छा लगा।
Pixel

24

स्टैक ओवरफ्लो का मतलब बिल्कुल यही होता है: स्टैक ओवरफ्लो। आमतौर पर कार्यक्रम में एक एक स्टैक होता है जिसमें स्थानीय-गुंजाइश चर और पते होते हैं जहां दिनचर्या समाप्त होने पर वापस लौटना होता है। यह स्टैक स्मृति में एक निश्चित मेमोरी रेंज के रूप में होता है, इसलिए यह सीमित है कि इसमें कितना मान हो सकता है।

यदि स्टैक खाली है तो आप पॉप नहीं कर सकते, यदि आप करते हैं तो आपको स्टैक अंडरफ्लो त्रुटि मिलेगी।

यदि स्टैक भरा हुआ है तो आप धक्का नहीं दे सकते, यदि आप करते हैं तो आपको स्टैक ओवरफ्लो त्रुटि मिलेगी।

तो स्टैक ओवरफ्लो दिखाई देता है जहां आप स्टैक में बहुत अधिक आवंटित करते हैं। उदाहरण के लिए, उल्लेखित पुनरावृत्ति में।

कुछ कार्यान्वयन कुछ रूपों की पुनरावृत्ति को अनुकूलित करते हैं। विशेष रूप से पूंछ पुनरावृत्ति। पूंछ पुनरावर्ती दिनचर्या दिनचर्या का रूप है जहां पुनरावर्ती कॉल एक अंतिम चीज के रूप में प्रकट होती है जो दिनचर्या करती है। इस तरह की रूटीन कॉल बस एक छलांग में कम हो जाती है।

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

अगर आप कर सकते हैं सबसे आसान बात आप अपने स्टैक आकार को बढ़ाने की कोशिश कर सकते हैं। यदि आप ऐसा नहीं कर सकते हैं, तो दूसरी सबसे अच्छी बात यह होगी कि क्या ऐसा कुछ है जो स्पष्ट रूप से स्टैक ओवरफ्लो का कारण बनता है। इसे रूटीन में कॉल करने से पहले और बाद में कुछ प्रिंट करके देखें। यह आपको असफल दिनचर्या का पता लगाने में मदद करता है।


4
क्या स्टैक अंडरफ्लो जैसी कोई चीज है ?
पचेरियर

5
असेंबली में एक स्टैक अंडरफ़्लो संभव है (आपके द्वारा पुश किए गए से अधिक पॉपिंग), हालांकि संकलित भाषाओं में यह असंभव के पास होगा। मुझे यकीन नहीं है, आप सी के एलाका () का कार्यान्वयन पा सकते हैं जो नकारात्मक आकारों का "समर्थन" करता है।
स्कोर_उंडर

2
स्टैक ओवरफ्लो का मतलब बिल्कुल यही होता है: स्टैक ओवरफ्लो। आमतौर पर प्रोग्राम में एक स्टैक होता है जिसमें लोकल-स्कोप वैरिएबल होते हैं -> नहीं, हर थ्रेड का अपना स्टैक होता है जिसमें हर
वेकेशन इंवोकेशन के

9

एक स्टैक ओवरफ्लो आमतौर पर नेस्टिंग फंक्शन कॉल द्वारा बहुत गहराई से बुलाया जाता है (विशेष रूप से आसान जब रिकर्सन का उपयोग करते हैं, यानी एक फ़ंक्शन जो खुद को कॉल करता है) या ढेर पर मेमोरी की एक बड़ी मात्रा आवंटित करना जहां ढेर का उपयोग करना अधिक उपयुक्त होगा।


1
उफ़, जावा टैग नहीं देखा
ग्रेग

इसके अलावा, मूल पोस्टर से यहां: घोंसले के कार्यों में बहुत गहराई से क्या? अन्य कार्य? और: कोई स्टैक या हीप को मेमोरी कैसे आवंटित करता है (क्योंकि, आप जानते हैं, मैंने स्पष्ट रूप से इन चीजों में से एक को बिना जाने किया है)।
जिग्गी

@Ziggy: हाँ, यदि एक फ़ंक्शन किसी अन्य फ़ंक्शन को कॉल करता है, जो अभी तक एक और फ़ंक्शन कॉल करता है, और इसी तरह, कई स्तरों के बाद, आपके प्रोग्राम में स्टैक ओवरफ़्लो होगा। [जारी है]
क्रिस जस्टर-यंग

[... जारी रखा] जावा में, आप सीधे स्टैक से मेमोरी आवंटित नहीं कर सकते हैं (जबकि सी में, आप कर सकते हैं, और यह तब देखने के लिए कुछ होगा), इसलिए इसका कारण होने की संभावना नहीं है। जावा में, सभी प्रत्यक्ष आवंटन ढेर से आते हैं, "नया" का उपयोग करके।
क्रिस जस्टर-यंग

@ क्रिसजेस्टर-यंग यह सच नहीं है कि अगर मेरे पास एक विधि में 100 स्थानीय चर हैं, तो यह सभी अपवादों के बिना ढेर पर चला जाता है?
पचेरियर

7

जैसा आप कहते हैं, आपको कुछ कोड दिखाने की आवश्यकता है। :-)

स्टैक ओवरफ्लो त्रुटि आमतौर पर तब होती है जब आपका फ़ंक्शन घोंसले को बहुत गहराई से बुलाता है। देखें कैसे होता है (हालांकि उस प्रश्न के मामले में, उत्तर जानबूझकर अतिप्रवाह का कारण बनता है) के कुछ उदाहरणों के लिए स्टैक ओवरफ़्लो कोड गोल्फ धागा ।


1
मैं पूरी तरह से कोड जोड़ना चाहूंगा, लेकिन जैसा कि मुझे नहीं पता कि स्टैक ओवरफ्लो का क्या कारण है, मुझे यकीन नहीं है कि क्या कोड जोड़ना है। सभी कोड जोड़ने पर लंगड़ा होगा, नहीं?
जिग्गी

क्या आपका प्रोजेक्ट ओपन-सोर्स है? यदि ऐसा है, तो बस एक सोर्सफ़ॉर्ज़ या जीथब अकाउंट बनाएं, और वहां अपना सारा कोड अपलोड करें। :-)
क्रिस जस्टर-यंग

यह एक महान विचार की तरह लगता है, लेकिन मैं एक ऐसा नॉब हूं जो मुझे यह भी नहीं पता है कि मुझे क्या अपलोड करना होगा। जैसे, पुस्तकालय कि मैं कक्षाओं का आयात कर रहा हूं जिसे मैं विस्तार कर रहा हूं आदि ... मेरे लिए सभी अज्ञात हैं। अरे यार: बुरा वक्त।
जिग्गी


5

StackOverflowErrorढेर के रूप OutOfMemoryErrorमें करने के लिए है।

असंबद्ध पुनरावर्ती कॉल के परिणामस्वरूप स्टैक स्पेस का उपयोग किया जा रहा है।

निम्नलिखित उदाहरण पैदा करता है StackOverflowError:

class  StackOverflowDemo
{
    public static void unboundedRecursiveCall() {
     unboundedRecursiveCall();
    }

    public static void main(String[] args) 
    {
        unboundedRecursiveCall();
    }
}

StackOverflowError यदि रिकार्सिव कॉल्स को अपूर्ण मेमोरी मेमोरी (बाइट्स में) के कुल योग को स्टैक आकार से अधिक (बाइट्स) में रोकने के लिए बाध्य किया गया है, तो बचने योग्य है।


3

यहां एक एकल लिंक की गई सूची को उलटने के लिए एक पुनरावर्ती एल्गोरिदम का उदाहरण दिया गया है। निम्न कल्पना (4 जी मेमोरी, इंटेल कोर i5 2.3GHz CPU, 64 बिट विंडोज 7) के साथ एक लैपटॉप पर, यह फ़ंक्शन 10,000 के करीब आकार की एक लिंक्ड सूची के लिए StackOverflow त्रुटि में चलेगा।

मेरा कहना है कि हमें पुनरावृत्ति का उपयोग विवेकपूर्ण तरीके से करना चाहिए, हमेशा सिस्टम के पैमाने को ध्यान में रखना चाहिए। अक्सर पुनरावृत्ति को पुनरावृत्त कार्यक्रम में परिवर्तित किया जा सकता है, जो बेहतर पैमाने पर होता है। (उसी एल्गोरिदम का एक पुनरावृत्त संस्करण पृष्ठ के निचले भाग में दिया गया है, यह 9 मिलीसेकंड में 1 मिलियन आकार की एक लिंक्ड सूची को उलट देता है।)

    private static LinkedListNode doReverseRecursively(LinkedListNode x, LinkedListNode first){

    LinkedListNode second = first.next;

    first.next = x;

    if(second != null){
        return doReverseRecursively(first, second);
    }else{
        return first;
    }
}

public static LinkedListNode reverseRecursively(LinkedListNode head){
    return doReverseRecursively(null, head);
}

समान एल्गोरिथ्म का निष्क्रिय संस्करण:

    public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}   

private static LinkedListNode doReverseIteratively(LinkedListNode x, LinkedListNode first) {

    while (first != null) {
        LinkedListNode second = first.next;
        first.next = x;
        x = first;

        if (second == null) {
            break;
        } else {
            first = second;
        }
    }
    return first;
}


public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}

मुझे लगता है कि JVM के साथ, यह वास्तव में कोई फर्क नहीं पड़ता कि आपके लैपटॉप की कल्पना क्या है।
केविन

3

A StackOverflowErrorजावा में रनटाइम त्रुटि है।

यह तब फेंक दिया जाता है जब JVM द्वारा आवंटित कॉल स्टैक मेमोरी की मात्रा पार हो जाती है।

StackOverflowErrorफेंके जाने का एक सामान्य मामला है , जब कॉल स्टैक अत्यधिक गहरी या अनंत पुनरावृत्ति के कारण बढ़ता है।

उदाहरण:

public class Factorial {
    public static int factorial(int n){
        if(n == 1){
            return 1;
        }
        else{
            return n * factorial(n-1);
        }
    }

    public static void main(String[] args){
        System.out.println("Main method started");
        int result = Factorial.factorial(-1);
        System.out.println("Factorial ==>"+result);
        System.out.println("Main method ended");
    }
}

स्टैक ट्रेस:

Main method started
Exception in thread "main" java.lang.StackOverflowError
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)

उपरोक्त मामले में, प्रोग्रामेटिक बदलाव करके इसे टाला जा सकता है। लेकिन अगर प्रोग्राम लॉजिक सही है और यह अभी भी होता है तो आपको स्टैक साइज को बढ़ाना होगा।


0

यह एक विशिष्ट मामला है java.lang.StackOverflowError... विधि पुनरावृत्ति रूप से अपने आप को बाहर नहीं निकलने के साथ बुला रही है doubleValue(),floatValue() आदि

Rational.java

    public class Rational extends Number implements Comparable<Rational> {
        private int num;
        private int denom;

        public Rational(int num, int denom) {
            this.num = num;
            this.denom = denom;
        }

        public int compareTo(Rational r) {
            if ((num / denom) - (r.num / r.denom) > 0) {
                return +1;
            } else if ((num / denom) - (r.num / r.denom) < 0) {
                return -1;
            }
            return 0;
        }

        public Rational add(Rational r) {
            return new Rational(num + r.num, denom + r.denom);
        }

        public Rational sub(Rational r) {
            return new Rational(num - r.num, denom - r.denom);
        }

        public Rational mul(Rational r) {
            return new Rational(num * r.num, denom * r.denom);
        }

        public Rational div(Rational r) {
            return new Rational(num * r.denom, denom * r.num);
        }

        public int gcd(Rational r) {
            int i = 1;
            while (i != 0) {
                i = denom % r.denom;
                denom = r.denom;
                r.denom = i;
            }
            return denom;
        }

        public String toString() {
            String a = num + "/" + denom;
            return a;
        }

        public double doubleValue() {
            return (double) doubleValue();
        }

        public float floatValue() {
            return (float) floatValue();
        }

        public int intValue() {
            return (int) intValue();
        }

        public long longValue() {
            return (long) longValue();
        }
    }

Main.java

    public class Main {

        public static void main(String[] args) {

            Rational a = new Rational(2, 4);
            Rational b = new Rational(2, 6);

            System.out.println(a + " + " + b + " = " + a.add(b));
            System.out.println(a + " - " + b + " = " + a.sub(b));
            System.out.println(a + " * " + b + " = " + a.mul(b));
            System.out.println(a + " / " + b + " = " + a.div(b));

            Rational[] arr = {new Rational(7, 1), new Rational(6, 1),
                    new Rational(5, 1), new Rational(4, 1),
                    new Rational(3, 1), new Rational(2, 1),
                    new Rational(1, 1), new Rational(1, 2),
                    new Rational(1, 3), new Rational(1, 4),
                    new Rational(1, 5), new Rational(1, 6),
                    new Rational(1, 7), new Rational(1, 8),
                    new Rational(1, 9), new Rational(0, 1)};

            selectSort(arr);

            for (int i = 0; i < arr.length - 1; ++i) {
                if (arr[i].compareTo(arr[i + 1]) > 0) {
                    System.exit(1);
                }
            }


            Number n = new Rational(3, 2);

            System.out.println(n.doubleValue());
            System.out.println(n.floatValue());
            System.out.println(n.intValue());
            System.out.println(n.longValue());
        }

        public static <T extends Comparable<? super T>> void selectSort(T[] array) {

            T temp;
            int mini;

            for (int i = 0; i < array.length - 1; ++i) {

                mini = i;

                for (int j = i + 1; j < array.length; ++j) {
                    if (array[j].compareTo(array[mini]) < 0) {
                        mini = j;
                    }
                }

                if (i != mini) {
                    temp = array[i];
                    array[i] = array[mini];
                    array[mini] = temp;
                }
            }
        }
    }

परिणाम

    2/4 + 2/6 = 4/10
    Exception in thread "main" java.lang.StackOverflowError
    2/4 - 2/6 = 0/-2
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
    2/4 * 2/6 = 4/24
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
    2/4 / 2/6 = 12/8
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)

यहाँ StackOverflowErrorOpenJDK 7 में स्रोत कोड है


0

एक क्रंच में, नीचे की स्थिति स्टैक ओवरफ्लो त्रुटि लाएगी।

public class Example3 {

public static void main(String[] args) {

    main(new String[1]);

}

}


-1

यहाँ एक उदाहरण है

public static void main(String[] args) {
    System.out.println(add5(1));
}

public static int add5(int a) {
    return add5(a) + 5;
}

एक StackOverflowError मूल रूप से है जब आप कुछ करने की कोशिश करते हैं, जो कि सबसे अधिक संभावना है, खुद को बुलाता है, और अनंत के लिए आगे बढ़ता है (या जब तक कि यह StackOverflowError नहीं देता)।

add5(a) खुद को बुलाएगा, और फिर खुद को फिर से कॉल करेगा, और इसी तरह।


-1

शब्द "स्टैक ओवररन (अतिप्रवाह)" का उपयोग अक्सर किया जाता है लेकिन एक मिथ्या नाम; हमले स्टैक को ओवरफ्लो नहीं करते हैं लेकिन स्टैक पर बफ़र्स होते हैं।

- प्रोफेसर डॉ। डायटर गोलमन के व्याख्यान स्लाइड से

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