Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نمط الهادم (Destructor Pattern)

جزء من قسم Object Oriented Programming في رحلة C على Coddy — الدرس 13 من 61.

كل كائن يتم إنشاؤه باستخدام malloc يجب تحريره في النهاية. تماماً كما كتبنا دالة create_ للتعامل مع التخصيص، نكتب دالة free_ للتعامل مع عملية التنظيف. هذا هو نمط المدمر (destructor pattern).

الفكرة الأساسية هي أن عملية التحرير (freeing) يجب أن تتم بترتيب عكسي لعملية التخصيص (allocation). إذا قام المنشئ (constructor) بتخصيص الأعضاء الداخليين أولاً ثم الـ struct نفسه، فيجب على المدمر (destructor) تحرير أعضاء الـ struct أولاً، ثم الـ struct نفسه:

typedef struct {
    char *name;
    int age;
} Person;

void free_person(Person *p) {
    if (p == NULL) return;  // التحقق من السلامة
    free(p->name);          // تحرير العضو الداخلي أولاً
    free(p);                // ثم تحرير الهيكل نفسه
}

يمنع التحقق من NULL في البداية الانهيارات في حال قام شخص ما بتمرير مؤشر غير صالح بالخطأ. بعد تحرير سلسلة name الداخلية، نقوم بتحرير الـ struct نفسه. إذا قمنا بتحرير p أولاً، فسنفقد إمكانية الوصول إلى p->name مما يتسبب في تسرب للذاكرة.

استخدام الـ destructor بسيط ومباشر:

Person *alice = create_person("Alice", 30);
// ... استخدم alice ...
free_person(alice);  // قم بالتنظيف عند الانتهاء

يضمن هذا النمط تحرير جميع الذاكرة بشكل صحيح. وبدونه، سيؤدي كل كائن تنشئه إلى تسريب الذاكرة حتى ينفد برنامجك.

challenge icon

التحدي

سهل

لنقم ببناء وحدة Movie توضح دورة حياة الكائن الكاملة — الإنشاء والتدمير. ستتدرب على كتابة دالة مدمرة (destructor) تقوم بتنظيف جميع الذاكرة المخصصة بشكل صحيح وبالترتيب الصحيح.

ستقوم بإنشاء ثلاثة ملفات:

  • movie.h: قم بالتصريح عن هيكل Movie يحتوي على عضوين: char *title (سلسلة نصية مخصصة ديناميكيًا) و int year. قم بالتصريح عن كل من المنشئ create_movie الذي يأخذ عنوانًا وسنة، والمدمر free_movie الذي يأخذ مؤشر Movie. استخدم حراس التضمين (include guards) مع الرمز MOVIE_H.
  • movie.c: قم بتنفيذ كلتا الدالتين. يجب أن يقوم المنشئ بتخصيص ذاكرة للهيكل وسلسلة العنوان الخاصة به (لا تنسَ النهاية الصفرية null terminator). يجب أن يقوم المدمر بتحرير الذاكرة بترتيب عكسي للتخصيص — أولاً سلسلة title الداخلية، ثم الهيكل نفسه. قم بتضمين فحص NULL في بداية المدمر الخاص بك من أجل السلامة.
  • main.c: قم بإنشاء فيلم، واعرض معلوماته، ثم قم بتنظيف الذاكرة بشكل صحيح.

ستتلقى مدخلين: عنوان الفيلم (سلسلة نصية) و سنة الإصدار (عدد صحيح).

في ملفك الرئيسي، استخدم create_movie لإنشاء فيلم جديد، واطبع معلوماته، ثم استدعِ free_movie لتحرير كل الذاكرة. بعد التحرير، اطبع رسالة تأكيد.

اطبع المخرجات بهذا التنسيق:

Movie: {title} ({year})
Memory freed

على سبيل المثال، مع المدخلات Inception و 2010، ستكون المخرجات:

Movie: Inception (2010)
Memory freed

تذكر: المفتاح للمدمر الصحيح هو التحرير بترتيب عكسي. كل ما يخصصه المنشئ أولاً يتم تحريره آخراً، وكل ما يخصصه آخراً يتم تحريره أولاً.

ورقة مرجعية

يجب تحرير كل كائن يتم إنشاؤه باستخدام malloc باستخدام دالة مدمرة (destructor). تتبع الدوال المدمرة نمط تحرير الذاكرة بترتيب عكسي لعملية التخصيص.

الهيكل الأساسي للدالة المدمرة:

typedef struct {
    char *name;
    int age;
} Person;

void free_person(Person *p) {
    if (p == NULL) return;  // Safety check
    free(p->name);          // Free internal members first
    free(p);                // Then free the struct itself
}

المبادئ الأساسية:

  • قم دائمًا بتضمين فحص NULL في البداية لمنع الانهيارات (crashes)
  • قم بتحرير الأعضاء الداخليين قبل تحرير الهيكل (struct) نفسه
  • إذا قمت بتحرير الهيكل أولاً، فستفقد إمكانية الوصول إلى أعضائه وتتسبب في تسرب الذاكرة (memory leaks)

مثال على الاستخدام:

Person *alice = create_person("Alice", 30);
// ... use alice ...
free_person(alice);  // Clean up when done

جرّب بنفسك

#include <stdio.h>
#include <stdlib.h>
#include "movie.h"

int main() {
    char title[100];
    int year;
    
    // قراءة المدخلات
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: إنشاء فيلم باستخدام create_movie
    
    // TODO: طباعة معلومات الفيلم بالتنسيق التالي:
    // الفيلم: {title} ({year})
    
    // TODO: تحرير الفيلم باستخدام free_movie
    
    // TODO: طباعة "Memory freed"
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming