Yükleniyor...

Dinamik Bellek Yönetimi: new ve delete

Heap tahsisi, new/delete kullanımı ve RAII’ye hazırlık için en iyi pratikler.

C++ dilinde belleğin iki ana bölgesi vardır: Stack (yığın) ve Heap (küme). Stack alanı otomatik olarak yönetilirken, Heap alanındaki bellek programcı tarafından manuel olarak kontrol edilir. Dinamik bellek yönetimi, program çalışırken bellek ayırmak ve serbest bırakmak için kullanılır. Bu makalede new ve delete anahtar kelimeleriyle dinamik bellek kullanımını detaylı inceleyeceğiz.


1. Stack ve Heap Arasındaki Fark

ÖzellikStack (Otomatik)Heap (Dinamik)
YönetimOtomatik (derleyici tarafından)Programcı tarafından manuel
Yaşam süresiFonksiyon bitince otomatik silinirProgramcı silmezse bellekte kalır
HızÇok hızlıDaha yavaştır (dinamik yönetim)
Bellek boyutuKısıtlıDaha geniş
KullanımYerel değişkenlerDinamik nesneler, diziler

2. new Anahtar Kelimesi ile Bellek Ayırma

new operatörü, Heap üzerinde dinamik olarak bellek ayırır ve ayrılan belleğin adresini döndürür. Bu adres genellikle bir pointer değişkene atanır.


#include <iostream>
using namespace std;

int main() {
    int *ptr = new int; // 1 adet int için bellek ayır
    *ptr = 42;
    cout << "Değer: " << *ptr << endl;

    delete ptr; // Belleği serbest bırak
    ptr = nullptr; // Güvenli hale getir
}

Not: new ile ayrılan bellek, delete ile manuel olarak serbest bırakılmalıdır. Aksi halde bellek sızıntısı (memory leak) oluşur.


3. new ile Dinamik Diziler

Dinamik olarak dizi oluşturmak için new[] kullanılır. Boyut çalışma zamanında belirlenebilir.


#include <iostream>
using namespace std;

int main() {
    int n;
    cout << "Kaç elemanlı dizi istiyorsunuz? ";
    cin >> n;

    int *dizi = new int[n]; // n elemanlık dizi oluştur

    for (int i = 0; i < n; i++)
        dizi[i] = (i + 1) * 10;

    cout << "Dizi: ";
    for (int i = 0; i < n; i++)
        cout << dizi[i] << " ";

    delete[] dizi; // Belleği serbest bırak
    dizi = nullptr;
}

delete[] kullanımı önemlidir; normal delete sadece tek değişken için geçerlidir, dizilerde kullanılmaz.


4. Dinamik Bellek Ayırma ve Serbest Bırakma Adımları

  1. new → Heap üzerinde bellek ayırır.
  2. Pointer → Ayrılan bellek adresini tutar.
  3. Veri işlenir veya doldurulur.
  4. delete / delete[] → Bellek serbest bırakılır.
  5. Pointer = nullptr → Asılı (dangling) pointer engellenir.

5. Bellek Sızıntısı (Memory Leak) Nedir?

Dinamik olarak ayrılan belleğin serbest bırakılmaması durumunda bellekte kullanılmayan alanlar birikir. Bu duruma bellek sızıntısı denir ve uzun süre çalışan programlarda ciddi performans sorunlarına yol açabilir.


void OlumsuzOrnek() {
    int *p = new int(10);
    // delete p; // Unutuldu! Bellek sızıntısı
}

Çözüm: delete kullanarak bellek serbest bırakılmalıdır.


6. nullptr ve Bellek Güvenliği

C++11 öncesinde boş pointer’lar genellikle NULL ile temsil edilirdi. Modern C++’ta bunun yerine tür güvenli nullptr anahtar kelimesi kullanılır.


int *p = nullptr;

if (p == nullptr) {
    cout << "Pointer hiçbir adresi göstermiyor." << endl;
}

nullptr kullanmak, yanlış adres erişimlerini ve “çökme” hatalarını (segmentation fault) önlemeye yardımcı olur.


7. Dinamik Bellek ile Fonksiyon Kullanımı

Bellek dinamik olarak oluşturulup fonksiyona gönderilebilir. Bu yöntem özellikle dinamik dizilerde yaygındır.


void Doldur(int *p, int n) {
    for (int i = 0; i < n; i++)
        p[i] = (i + 1) * 2;
}

int main() {
    int *dizi = new int[5];
    Doldur(dizi, 5);

    for (int i = 0; i < 5; i++)
        cout << dizi[i] << " ";

    delete[] dizi;
}

8. new ile Obje Oluşturma

new sadece temel veri türlerinde değil, sınıf nesnelerinde de kullanılabilir.


#include <iostream>
using namespace std;

class Ogrenci {
public:
    string ad;
    Ogrenci(string a) : ad(a) {
        cout << ad << " oluşturuldu." << endl;
    }
    ~Ogrenci() {
        cout << ad << " silindi." << endl;
    }
};

int main() {
    Ogrenci *p = new Ogrenci("Ali");
    delete p; // destructor çağrılır
}

new ile oluşturulan nesnelerin delete ile silinmesi, otomatik olarak o nesnenin destructor metodunu çağırır.


9. Smart Pointer’lar (Modern C++ Yaklaşımı)

C++11 ile birlikte manuel delete işlemlerine alternatif olarak akıllı pointer’lar (smart pointers) tanıtılmıştır. Bunlar otomatik bellek yönetimi sağlar.


#include <iostream>
#include <memory>
using namespace std;

int main() {
    unique_ptr<int> p = make_unique<int>(100);
    cout << *p << endl; // 100
}

Smart pointer’lar, nesne kapsamdan çıktığında belleği otomatik olarak serbest bırakır. Bu sayede bellek sızıntıları ortadan kalkar.


10. TL;DR

  • new → Heap üzerinde bellek ayırır, adres döndürür.
  • delete → Belleği serbest bırakır (tek değişken).
  • new[] / delete[] → Dinamik diziler için kullanılır.
  • nullptr → boş pointer için güvenli tanımdır.
  • Bellek sızıntılarını önlemek için her new’e karşılık bir delete olmalıdır.
  • std::unique_ptr ve std::shared_ptr modern alternatiflerdir.
  • Tüm örnekler Visual Studio 2022 veya GCC 11+ ortamında çalıştırılabilir.

İlişkili Makaleler