الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

StackOverflowError لما يظهر و ليس لدي طريقة تكرر نفسها الى ماﻻ نهاية؟

بدأه sahraoui dhelim في 6 ديسمبر 2012 · 4 رد · 613 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السﻻم عليكم

سوالى بخصوص StackOverflowError

انا اعلم انها يحصل عند وجود طريقة تنادى نفسها بستمرار الى ماﻻنهاية و هو ما يسبب امتﻻء ال stack الخاصة بى الاستدعاء

المهم هذا هو الكود

public static BigInteger naive(BigInteger x,int n) throws PuissanceNegativeException{

	if(n==0){
    	return BigInteger.ONE;
	} else {
    	if(n==1){
     	return x;   
    	}else{
        	if(n > 1){

            	return ( x.multiply(Puissance.naive(x,(n-1))) );
        	}else{
        	throw new PuissanceNegativeException(); 
        	}
    	}   

	}
}

عندما استدعى

System.out.println("methode naive 2¹⁰⁰⁰= "+Puissance.naive(BigInteger.valueOf(2),1000));

يشتغل تمام لكن

System.out.println("methode naive 2¹⁰⁰⁰⁰= "+Puissance.naive(BigInteger.valueOf(2),100000));

يعطيني stackoverflowexception

و اذا كان هذه هي حدود قدرات ال stack فما هو الحل؟

#2

الحل أخي أن تعدل هيكل برنامجك وتتجنب أن تجعل الدالة تعيد إستدعاء نفسها. لأنه لو كان مثلاً حجم الجزء الخاص بالدالة في المكدس 10 بايتات، وجعلت الدالة تعيد إستدعاء نفسها 100,000 فسيصبح مجموع أحجام بيانات تلك الإستدعاءات مليون بايت.

هنا:

class Example {
    public static double methodA(double a, double b) {
        if(a == 0) return 1;
        if(b == 1) return a;

        return a * methodA(a, b-1);
    }

    public static double methodB(double a, double b) {
        if(a == 0) return 1;
        if(b == 1) return a;

        double r = a;

        while( b-- > 1 )
            r *= a;

        return r;
    }

    public static void main(String[] argv) {
        System.out.println(methodA(2, 100000));
        System.out.println(methodB(2, 100000));
    }
};

يمكن أن تسبب الوظيفة methodA الإستثناء StackOverflowError ولكن الأخرى التي تستخدم حلقة التكرار لن تسببه.

#3
Mr.B كتب:

الحل أخي أن تعدل هيكل برنامجك وتتجنب أن تجعل الدالة تعيد إستدعاء نفسها. لأنه لو كان مثلاً حجم الجزء الخاص بالدالة في المكدس 10 بايتات، وجعلت الدالة تعيد إستدعاء نفسها 100,000 فسيصبح مجموع أحجام بيانات تلك الإستدعاءات مليون بايت.

هنا:

class Example {
    public static double methodA(double a, double b) {
        if(a == 0) return 1;
        if(b == 1) return a;

        return a * methodA(a, b-1);
    }

    public static double methodB(double a, double b) {
        if(a == 0) return 1;
        if(b == 1) return a;

        double r = a;

        while( b-- > 1 )
            r *= a;

        return r;
    }

    public static void main(String[] argv) {
        System.out.println(methodA(2, 100000));
        System.out.println(methodB(2, 100000));
    }
};

يمكن أن تسبب الوظيفة methodA الإستثناء StackOverflowError ولكن الأخرى التي تستخدم حلقة التكرار لن تسببه.

كلامك على العين و الراس

لكن هذا هو المطلوب في التمرين ان ابرمج الدالة بطريقة naive

اي يجب ان التزم بي recursivite

هل هناك طريقة لجعل ال stack تخزن في hard drive اي ان تكون وهمية

مثل ما جعلت الحساب يكون في الذاكرة و ليس في الريجيستر بستعمال biginteger عوض int

هل يمكن تطبيق هذا المبدء على ال stack

و هل يمكن جعل هذا الكود بي tail recursion

تم تعديل هذه المشاركة بواسطة sahraoui dhelim في 7 ديسمبر 2012 في 10:00

#4

أخي بدل أن تحاول تعديل طريقة عمل آلة جافا عدل برنامجك. جعل وظيفة تعيد إستدعاء نفسها مرات كثيرة أو للأبد هذا "خطأ في البرنامج". يمكنك أن تزيد حجم المكدس مثلاً لـ5 ميجا:

> java Example
Exception in thread "main" java.lang.StackOverflowError
        at Example.methodA(Example.java:6)
        at Example.methodA(Example.java:6)
...
        at Example.methodA(Example.java:6)

> java -Xss5m Example
Infinity
Infinity
>

لكن الخطأ سيعاود الظهور بمجرد زيادة مرات الإستدعاء.

#5
Mr.B كتب:

جعل وظيفة تعيد إستدعاء نفسها مرات كثيرة أو للأبد هذا "خطأ في البرنامج".

هل افهم من كلامك اننا لا نستطيع حل المشاكل بطريقة تراجعية اذا كان عدد استدعائها كبير

تم تعديل هذه المشاركة بواسطة sahraoui dhelim في 7 ديسمبر 2012 في 22:43

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…