Menu
Coddy logo textTech

Destructor Deseni

Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 13 / 61.

malloc ile oluşturulan her nesne en sonunda serbest bırakılmalıdır. Tıpkı bellek tahsisini (allocation) yönetmek için bir create_ fonksiyonu yazdığımız gibi, temizleme işlemini yönetmek için de bir free_ fonksiyonu yazarız. Bu, yıkıcı (destructor) desenidir.

Temel içgörü, serbest bırakma işleminin tahsis sırasının tersine gerçekleşmesi gerektiğidir. Eğer kurucunuz (constructor) önce dahili üyeleri ve ardından yapının (struct) kendisini tahsis ettiyse, yıkıcınız (destructor) önce yapının üyelerini, ardından yapının kendisini serbest bırakmalıdır:

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

void free_person(Person *p) {
    if (p == NULL) return;  // Güvenlik kontrolü
    free(p->name);          // Önce dahili üyeyi serbest bırak
    free(p);                // Sonra yapının kendisini serbest bırak
}

Başlangıçtaki NULL kontrolü, birisi yanlışlıkla geçersiz bir işaretçi gönderirse çökmeleri önler. Dahili name dizgisini serbest bıraktıktan sonra, yapının kendisini serbest bırakırız. Eğer önce p'yi serbest bıraksaydık, p->name'e erişimi kaybederdik ve bir bellek sızıntısına neden olurduk.

Destructor'ı kullanmak oldukça basittir:

Person *alice = create_person("Alice", 30);
// ... alice'i kullanın ...
free_person(alice);  // İşlem bittiğinde temizleyin

Bu desen, tüm belleğin düzgün bir şekilde serbest bırakılmasını sağlar. Bu olmadan, oluşturduğunuz her nesne programınızın belleği bitene kadar bellek sızdıracaktır.

challenge icon

Görev

Kolay

Hem oluşturma hem de yok etme süreçlerini içeren tam bir nesne yaşam döngüsünü gösteren bir Movie modülü oluşturalım. Ayrılan tüm belleği doğru sırayla düzgün bir şekilde temizleyen bir yıkıcı (destructor) fonksiyonu yazma pratiği yapacaksınız.

Üç dosya oluşturacaksınız:

  • movie.h: İki üyeye sahip bir Movie yapısı (struct) bildirin: char *title (dinamik olarak ayrılmış bir dize) ve int year. Hem bir başlık ve yıl alan bir yapıcı (constructor) create_movie, hem de bir Movie işaretçisi alan bir yıkıcı (destructor) free_movie bildirin. MOVIE_H sembolü ile include guard kullanın.
  • movie.c: Her iki fonksiyonu da uygulayın. Yapıcınız, yapı ve başlık dizesi için bellek ayırmalıdır (null sonlandırıcıyı unutmayın). Yıkıcınız, belleği ayırma sırasının tersine serbest bırakmalıdır—önce dahili title dizesini, ardından yapının kendisini. Güvenlik için yıkıcınızın başına bir NULL kontrolü ekleyin.
  • main.c: Bir film oluşturun, bilgilerini görüntüleyin ve ardından belleği düzgün bir şekilde temizleyin.

İki girdi alacaksınız: film başlığı (bir dize) ve yayın yılı (bir tam sayı).

Ana dosyanızda, yeni bir film oluşturmak için create_movie kullanın, bilgilerini yazdırın ve ardından tüm belleği serbest bırakmak için free_movie çağırın. Serbest bıraktıktan sonra bir onay mesajı yazdırın.

Çıktıyı şu formatta yazdırın:

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

Örneğin, Inception ve 2010 girdileriyle çıktı şöyle olacaktır:

Movie: Inception (2010)
Memory freed

Unutmayın: düzgün bir yıkıcının anahtarı, ters sırada serbest bırakmaktır. Yapıcınızın ilk ayırdığı şey en son serbest bırakılır ve en son ayırdığı şey ilk önce serbest bırakılır.

Kopya kağıdı

malloc ile oluşturulan her nesne, bir yıkıcı (destructor) fonksiyon kullanılarak serbest bırakılmalıdır. Yıkıcılar, belleği ayırma işleminin tersi sırayla serbest bırakma modelini izler.

Temel yıkıcı yapısı:

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
}

Temel ilkeler:

  • Çökmeleri önlemek için her zaman başlangıçta bir NULL kontrolü ekleyin
  • Yapının (struct) kendisini serbest bırakmadan önce dahili üyeleri serbest bırakın
  • Önce yapıyı serbest bırakırsanız, üyelerine erişimi kaybedersiniz ve bellek sızıntılarına (memory leaks) neden olursunuz

Kullanım örneği:

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

Kendin dene

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

int main() {
    char title[100];
    int year;
    
    // Girdiyi oku
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: create_movie kullanarak bir film oluşturun
    
    // TODO: Film bilgilerini şu formatta yazdırın:
    // Movie: {title} ({year})
    
    // TODO: free_movie kullanarak filmi serbest bırakın
    
    // TODO: "Memory freed" yazdırın
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Object Oriented Programming bölümündeki tüm dersler