التحقق من فشل التخصيص
جزء من قسم Logic & Flow في رحلة C على Coddy — الدرس 34 من 63.
بينما تعد malloc() أداة قوية لتخصيص الذاكرة الديناميكي، هناك حقيقة بالغة الأهمية يجب أن تفهمها: يمكن لـ malloc() أن تفشل. فعندما تنفد الذاكرة المتاحة في النظام، لا تستطيع malloc() تلبية طلبك وتعيد NULL بدلاً من عنوان ذاكرة صالح.
هذا يعني أنه في كل مرة تستخدم فيها malloc()، يجب عليك التحقق مما إذا كانت العملية قد نجحت قبل محاولة استخدام المؤشر الذي تم إرجاعه. استخدام مؤشر NULL سيؤدي إلى تعطل برنامجك مع حدوث خطأ في التجزئة (segmentation fault).
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // الخروج من البرنامج أو معالجة الخطأ
}
// من الآمن استخدام ptr هنا
*ptr = 42;إن فحص NULL هذا ليس اختيارياً - فهو ضروري لكتابة برامج C قوية. حتى لو كانت حالات فشل تخصيص الذاكرة نادرة في الأنظمة الحديثة، فقد تحدث، خاصة في البيئات محدودة الموارد أو عند طلب كميات كبيرة من الذاكرة. تتضمن أكواد C الاحترافية دائماً هذه الفحوصات لمنع الانهيارات وتوفير معالجة سلسة للأخطاء.
التحدي
سهلاكتب برنامجاً بلغة C يوضح المعالجة الصحيحة للأخطاء عند استخدام malloc() لتخصيص الذاكرة الديناميكي. يجب أن يقوم برنامجك بما يلي:
- قراءة عدد صحيح
nمن المستخدم يمثل عدد الأعداد الصحيحة المراد تخزينها - استخدام
malloc()معsizeof()لتخصيص ذاكرة ديناميكياً لمصفوفة مكونة منnمن الأعداد الصحيحة - التحقق مما إذا كان تخصيص الذاكرة ناجحاً عن طريق اختبار ما إذا كان المؤشر المرتجع هو
NULL - إذا فشل التخصيص، اطبع
Memory allocation failed!وأنهِ البرنامج - إذا نجح التخصيص، اطبع
Memory allocation successful! - قراءة
nمن قيم الأعداد الصحيحة من المستخدم وتخزينها في المصفوفة المخصصة - حساب وطباعة مجموع كل القيم بالتنسيق التالي:
Sum: [value] - طباعة إجمالي البايتات المخصصة بالتنسيق التالي:
Bytes allocated: [value]
تذكر تضمين الترويسة <stdlib.h> لاستخدام malloc(). يجب أن يوضح برنامجك الممارسة الأساسية للتحقق من فشل التخصيص قبل محاولة استخدام الذاكرة المخصصة.
على سبيل المثال، إذا كان الإدخال هو:
4
10 20 30 40يجب أن يكون المخرج:
Memory allocation successful!
Sum: 100
Bytes allocated: 16يؤكد هذا التحدي على الأهمية البالغة للبرمجة الدفاعية عند التعامل مع تخصيص الذاكرة الديناميكي، مما يضمن أن برامجك تعالج حالات فشل تخصيص الذاكرة المحتملة بسلاسة بدلاً من الانهيار بشكل غير متوقع.
ورقة مرجعية
تحقق دائمًا مما إذا كانت malloc() تعيد NULL قبل استخدام الذاكرة المخصصة:
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // اخرج من البرنامج أو تعامل مع الخطأ
}
// من الآمن استخدام ptr هنا
*ptr = 42;يمكن أن تفشل malloc() عندما تنفد الذاكرة المتاحة في النظام. سيؤدي استخدام مؤشر NULL إلى حدوث خطأ في التجزئة (segmentation fault). يعد التحقق من NULL هذا ضروريًا لكتابة برامج C قوية ومنع الانهيارات.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
int main() {
// قراءة عدد الأعداد الصحيحة
int n;
scanf("%d", &n);
// TODO: اكتب كودك هنا
// - استخدم malloc() لتخصيص ذاكرة لـ n من الأعداد الصحيحة
// - تحقق مما إذا كان التخصيص ناجحاً
// - التعامل مع حالتي النجاح والفشل
// - قراءة الأعداد الصحيحة وتخزينها
// - حساب المجموع والبايتات المخصصة
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1أساسيات المؤشرات
ما هو المؤشر؟الإعلان عن المؤشراتعامل العنوان (&)عامل إلغاء المرجعية (*)مؤشرات NULLمراجعة: أساسيات المؤشرات4مشروع: أداة نصوص بسيطة
نظرة عامة على المشروععد الأحرف2المؤشرات والمصفوفات
أسماء المصفوفات كمؤشراتعناصر المصفوفة - المؤشراتالعمليات الحسابية على المؤشراتمقارنة المؤشراتمراجعة: التنقل في المصفوفة باستخدام المؤشرات5المؤشرات والدوال
التمرير بالقيمةتمرير المؤشرات إلى الدوالتعديل المتغيرات عبر المؤشراتمثال كلاسيكي: التبديلتمرير المصفوفات إلى الدوالملخص: وسائط المؤشرات في الدوال8الهياكل والمؤشرات
المؤشرات إلى الهياكلعامل السهم (->)تمرير الهياكل بالقيمةتمرير مؤشرات الهياكلالتخصيص الديناميكي للهياكلمراجعة: تعديل الهياكل باستخدام المؤشرات11تحديات المراجعة النهائية
مراجعة: دمج السلاسل النصية الديناميكيمراجعة: مصفوفة من الـ Structsمراجعة: عداد تكرار الكلمات3مصفوفات الأحرف والسلاسل النصية
السلاسل النصية كمصفوفات charالمُنهي الصفري (Null Terminator)إدخال السلاسل النصية باستخدام scanfاستخدام strlen()استخدام strcpy()استخدام strcat()استخدام strcmp()مراجعة: دوال السلاسل النصية الأساسية