0Pricing
C Academy · درس

تجنّب Stack Overflow

حافظ على حدود الاستدعاء递ռقي

تجنّب Stack Overflow درس مجاني في C Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C Academy 4 دروس في المجموع.

ما تجاوز سعة المكدس؟

يملك مكدس الاستدعاءات حجمًا محدودًا. ويستخدم كل استدعاء دالة جزءًا منه للمعاملات والمتغيرات المحلية.

إذا تعمقت العودية أكثر من اللازم، يمتلئ المكدس ويتعطل البرنامج بسبب تجاوز سعة المكدس.

غياب الحالة الأساسية

السبب الأكثر شيوعًا هو وجود حالة أساسية لا يتم الوصول إليها أبدًا. يؤدي ذلك إلى التكرار بلا نهاية ثم تجاوز سعة المكدس.

لا تشغّلوا هذا النوع من الدوال؛ بل ادرسوا سبب فشله.

int broken(int n) {
    /* no base case: never stops */
    return broken(n + 1);
}

المعامل لا يتناقص

حتى مع وجود حالة أساسية، يجب أن يتحرك المعامل باتجاهها. يزداد n هنا، ولذلك لا يصل أبدًا إلى 0.

تحققوا دائمًا من أن كل استدعاء يقترب من شرط التوقف.

int oops(int n) {
    if (n == 0) return 0;
    return oops(n + 1); /* wrong direction */
}

نسخة صحيحة

يؤدي تصحيح الاتجاه إلى إنهاء التنفيذ. ينخفض n الآن باتجاه الحالة الأساسية 0.

#include <stdio.h>

int good(int n) {
    if (n == 0) return 0;
    return n + good(n - 1);
}

int main(void) {
    printf("%d\n", good(10));
    return 0;
}

حدود العمق حقيقية

حتى العودية الصحيحة قد تتسبب في تجاوز السعة إذا كانت عميقة جدًا. قد يتجاوز استدعاء دالة على ملايين المستويات سعة المكدس، الذي لا يتجاوز غالبًا بضعة ميغابايتات.

عند التعامل مع أعماق هائلة، فضّلوا التكرار.

تحويل العودية العميقة إلى حلقة

إذا ازداد عمق العودية مع حجم المدخلات، فانتقلوا إلى حلقة. فهذا يتجنب تراكم آلاف الإطارات.

تجمع الحلقة أدناه الأعداد من 1 إلى n كبير بأمان باستخدام ذاكرة ثابتة.

#include <stdio.h>

int main(void) {
    long total = 0;
    for (int i = 1; i <= 1000000; i++)
        total += i;
    printf("%ld\n", total);
    return 0;
}

تقليل العمق بالتقسيم والتغلب

يؤدي تقسيم العمل إلى نصفين إلى إبقاء العمق صغيرًا. ويجعل جمع نطاق بتقسيمه إلى نصفين العمق يزداد بمقدار لوغاريتم الحجم بدلًا من ازدياده خطيًا.

long range_sum(int lo, int hi) {
    if (lo == hi) return lo;
    int mid = (lo + hi) / 2;
    return range_sum(lo, mid) + range_sum(mid + 1, hi);
}

انتبهوا إلى المصفوفات المحلية الكبيرة

تجعل المتغيرات المحلية الكبيرة كل إطار ثقيلًا، ولذلك يمتلئ المكدس بسرعة أكبر.

تجنبوا التصريح عن مصفوفات كبيرة داخل دالة عودية؛ مرروا المؤشرات أو استخدموا الكومة بدلًا من ذلك.

void heavy(int n) {
    int buffer[10000]; /* big frame each call */
    if (n == 0) return;
    heavy(n - 1);
}

استخدام متغير جامع

يؤدي تمرير مجموع جارٍ بوصفه متغيرًا جامعًا إلى إبقاء كل إطار صغيرًا، ويجعل العودية ذات بنية ذيلية.

يمكن لبعض المصرّفات بعد ذلك إعادة استخدام إطار واحد.

#include <stdio.h>

long sum_acc(int n, long acc) {
    if (n == 0) return acc;
    return sum_acc(n - 1, acc + n);
}

int main(void) {
    printf("%ld\n", sum_acc(100, 0));
    return 0;
}

قائمة تحقق للسلامة

قبل الوثوق بدالة عودية، تحققوا مما يلي:

1. هل توجد حالة أساسية؟
2. هل يقترب كل استدعاء منها؟
3. هل يمكن أن يصبح العمق هائلًا مع المدخلات الكبيرة؟

إذا كان العمق قد يتضخم، فاستخدموا حلقة بدلًا من ذلك.

الاختبار باستخدام مدخلات صغيرة

اختبروا العودية دائمًا أولًا باستخدام مدخلات صغيرة جدًا يمكنكم التحقق منها يدويًا.

إذا نجحت الحالات الصغيرة وبقي العمق محدودًا، فيمكنكم زيادة الحجم بثقة.

تحقق سريع

حددوا الإصلاح الأكثر أمانًا.

مراجعة

يحدث تجاوز سعة المكدس عندما تصبح العودية عميقة جدًا أو لا تتوقف أبدًا. وفروا دائمًا حالة أساسية يمكن الوصول إليها، وقلّصوا المعامل في كل استدعاء، وأبقوا الإطارات خفيفة، وانتقلوا إلى التكرار عندما يزداد العمق مع حجم المدخلات.

الأسئلة الشائعة

هل درس «تجنّب Stack Overflow» مجاني؟

نعم — نص درس «تجنّب Stack Overflow» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C Academy 4 دروس في المجموع.

ماذا ستتعلم في «تجنّب Stack Overflow»؟

حافظ على حدود الاستدعاء递ռقي تتمرن على C Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C Academy؟

لا تُشترط خبرة سابقة. C Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تجنّب Stack Overflow»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C Academy هذا؟

نعم. كل درس في C Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. كيف يعمل الاستدعاء递归ي
  2. مسائل递归ية كلاسيكية
  3. الاستدعاء递ռقي مقابل التكرار
  4. تجنّب Stack Overflow
← العودة إلى C Academy