🚀 BAŞTAN SONA C DİLİ BÖLÜM-8: Dinamik Bellek Yönetimi (`malloc`, `calloc`, `realloc`, `free`) 🧠

Konu Özeti

C dilinde dinamik bellek yönetimi, stack ve heap mimarisi üzerinden açıklanıyor. malloc, calloc, realloc ve free fonksiyonlarının kullanımı, bellek sızıntılarını önleme yöntemleri ve çalışma zamanında dizi boyutlandırma örneklerle detaylandırılıyor. Kapsamlı bir dinamik dizi uygulamasıyla konu pekiştiriliyor.

🚀 BAŞTAN SONA C DİLİ BÖLÜM-8: Dinamik Bellek Yönetimi (`malloc`, `calloc`, `realloc`, `free`) 🧠

Selamlar! Serimizin 8. bölümüne hoş geldiniz.

Önceki bölümde dizileri, metin (String) mantığını ve `<string.h>` kütüphanesini incelemiştik. Şu ana kadar tanımladığımız tüm dizilerin boyutları **derleme zamanında (compile-time)** sabitti (Örn: `int dizi[100];`). Peki ya kullanıcının kaç eleman gireceğini program çalışmadan önce bilmiyorsak? Boşuna 1000 elemanlık yer açıp belleği israf mı edeceğiz?

İşte bu noktada devreye C dilinin en büyük gücü olan **Dinamik Bellek Yönetimi (Dynamic Memory Allocation - DMA)** giriyor! Bu işlemler için programımıza mutlaka **`<stdlib.h>`** kütüphanesini dahil etmemiz gerekir.

---

📌 1. Bellek Mimarisi: Stack vs Heap 🏛️

C programları çalışırken RAM'i iki ana bölüme ayırır:

1. **Stack (Yığın):** Normal değişkenlerin (`int a = 5;` veya `char isim[20];`) tutulduğu yerdir. Boyutları derleme anında bellidir. Fonksiyon bitince bellek otomatik temizlenir. Oldukça hızlı ama kapasitesi kısıtlıdır.
2. **Heap (Öbek):** Dinamik belleğin ayrıldığı, devasa boş bellek havuzudur. Buradan yer ayırmak ve işi bitince geri iade etmek **tamamen programcının (sizin) sorumluluğunuzdadır.**

---

🛠️ 2. `malloc()` (Memory Allocation) 📦

Heap bölgesinden **belirtilen byte kadar** tek parça bellek alanı ayırır. Ayırdığı alanın başlangıç adresini `void*` (türsüz pointer) olarak döner. Bu alanın içi temizlenmez, rastgele **çöp değerler (garbage values)** içerir.

Sözdizimi: `(Tur*) malloc(Eleman_Sayisi * sizeof(Tur));`

#include <stdio.h>
#include <stdlib.h> // malloc, free için zorunlu!

int main() {
int n;
printf("Kac adet sayi gireceksiniz?: ");
scanf("%d", &n);

// Heap'ten n adet int boyutunda (n * 4 byte) yer ayırıyoruz
int *ptr = (int*) malloc(n * sizeof(int));

// KURAL 1: Bellek ayrılabildi mi kontrol et! (RAM dolmuş olabilir)
if (ptr == NULL) {
printf("HATA: Bellekte yeterli yer yok!\n");
return 1; // Programı hata koduyla bitir
}

printf("Bellek tahsisi basarili!\n");
return 0;
}

---

🧼 3. `calloc()` (Contiguous Allocation) 🧽

`malloc` ile aynı işi yapar ancak iki önemli farkı vardır:
1. Parametreleri farklıdır: `(Eleman Sayısı, Her Birinin Boyutu)`.
2. Ayırdığı bellek alanındaki tüm bitleri otomatik olarak **0 ile doldurur (temizler).**

Sözdizimi: `(Tur*) calloc(Eleman_Sayisi, sizeof(Tur));`

// 5 adet int için yer ayırır ve hepsine 0 değerini atar
int *ptr = (int*) calloc(5, sizeof(int));

---

📏 4. `realloc()` (Re-allocation) 📐

Daha önceden `malloc` veya `calloc` ile ayırdığınız bir bellek alanının **boyutunu çalışma zamanında büyütmek veya küçültmek** isterseniz kullanılır. Orijinal verileri koruyarak yeni boyuta adapte eder.

Sözdizimi: `(Tur*) realloc(Eski_Pointer, Yeni_Toplam_Byte);`

// Dizinin boyutunu n'den (n+5)'e çıkaralım
ptr = (int*) realloc(ptr, (n + 5) * sizeof(int));

---

🚨 5. `free()` ve Memory Leak (Bellek Sızıntısı) 💣

C dilinde, Java veya C#'taki gibi otomatik Çöp Toplayıcı (Garbage Collector) **YOKTUR**. Heap'ten ayırdığınız belleği işiniz bittiğinde sisteme **iade etmek ZORUNDASINIZ.**

Eğer iade etmezseniz ve program uzun süre çalışırsa (örneğin bir oyun veya sunucu), RAM yavaş yavaş dolar ve sonunda sistem kilitlenir. Buna **Memory Leak (Bellek Sızıntısı)** denir.

// İşi biten bellek alanını sisteme iade eder
free(ptr);

// Güvenlik Pratiği (Dangling Pointer'ı önlemek için):
ptr = NULL;

---

🧪 6. Kapsamlı Dinamik Dizi Örneği 🚀

Gelin boyutu kullanıcı tarafından belirlenen, elemanları atanan ve işi bitince hafızası temizlenen tam teşekküllü bir program yazalım.

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

int main() {
int n, i;
int *notlar;

printf("Sinif mevcudunu giriniz: ");
scanf("%d", &n);

// 1. Adım: Bellek Tahsisi
notlar = (int*) malloc(n * sizeof(int));

// 2. Adım: NULL Kontrolü
if (notlar == NULL) {
printf("Hata: Bellek tahsis edilemedi!\n");
return -1;
}

// 3. Adım: Veri Girişi (Array gibi kullanılabilir)
for (i = 0; i < n; i++) {
printf("%d. Ogrencinin Notu: ", i + 1);
scanf("%d", &notlar); // veya (notlar + i)
}

// 4. Adım: Verileri Ekrana Yazdırma
printf("\n--- NOT LISTESI ---\n");
for (i = 0; i < n; i++) {
printf("Ogrenci %d: %d\n", i + 1, notlar);
}

// 5. Adım: Tahsis Edilen Belleği Temizleme (Hayat Kurtarır!)
free(notlar);
notlar = NULL; // Güvenlik amacıyla sıfırlama

return 0;
}

---

📝 Bölüm Özeti ve Gelecek Bölüm 🔮

Bu bölümde Stack/Heap mantığını, C dilinin kalbi olan DMA (Dinamik Bellek Yönetimi) fonksiyonlarını (`malloc`, `calloc`, `realloc`) ve uygulamalarımızı çökmekten kurtaran `free()` komutunu öğrendik.

👉 **Bölüm 9'da Bizi Ne Bekliyor?**
• Kendi Veri Tiplerimizi Oluşturma: **Yapılar (`struct`)** 🏗️
• `struct` Tanımlama ve Nesne (Değişken) Üretme
• **`typedef`** Anahtar Kelimesi ile İsimlendirme
• Struct Dizileri (Veritabanı mantığına hazırlık)

• Bellek Optimizasyonu: **`union`** (Birlik) Kavramı

Sorularınızı konu altından iletebilirsiniz. Bir sonraki bölümde görüşmek üzere! 💻✨

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
136,824Threads
3,308,553Messages
328,647Members
SimpsonMichaelLatest member
Top Bottom