Menu
Coddy logo textTech

Dinamik Bellek (new/delete)

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 14 / 104.

Artık işaretçileri ve referansları anladığınıza göre, onları dinamik bellek ayırma ile işe koşalım. new ve delete operatörleri, çalışma zamanında yığında (heap) nesneler oluşturmanıza ve yok etmenize olanak tanır.

Bellek ayırmak ve ona bir işaretçi (pointer) geri almak için new kullanın:

int* num = new int;        // Tek bir tam sayı ayır
*num = 42;                 // İşaretçi aracılığıyla değer ata

Player* player = new Player("Hero");  // Nesne ayır

Belleği serbest bırakmak için her new ifadesinin eşleşen bir delete ifadesi olmalıdır:

delete num;      // Tek bir nesneyi serbest bırak
delete player;   // Yıkıcıyı çağırır, ardından belleği serbest bırakır

Diziler için new[] ve delete[] kullanın:

int* scores = new int[5];    // 5 tam sayıdan oluşan dizi tahsis et
scores[0] = 100;

delete[] scores;             // Diziyi serbest bırak - köşeli parantezlere dikkat edin!

Kaçınılması gereken yaygın hatalar:

// Bellek sızıntısı - silmeyi unuttunuz
int* ptr = new int(10);
ptr = new int(20);    // İlk tahsise erişim kaybedildi!

// Sarkan işaretçi (Dangling pointer) - sildikten sonra kullanma
delete ptr;
*ptr = 5;             // Tanımsız davranış!

// Uyumsuz silme
int* arr = new int[10];
delete arr;           // Yanlış! delete[] olmalı

Sildikten sonra, yanlışlıkla yeniden kullanımı önlemek için işaretçileri nullptr olarak ayarlayın. Manuel bellek yönetimi hataya açıktır; bu nedenle modern C++, bir sonraki adımda inceleyeceğimiz akıllı işaretçileri tercih eder.

challenge icon

Görev

Kolay

new ve delete ile dinamik bellek tahsisini gösteren basit bir mesaj depolama sistemi oluşturalım.

Kodunuzu düzenlemek için iki dosya oluşturacaksınız:

  • MessageBox.h: Bir dizi mesajı dinamik olarak yöneten bir MessageBox sınıfı tanımlayın. Sınıf şunlara sahip olmalıdır:
    • Dinamik olarak tahsis edilmiş bir string dizisine işaret eden özel (private) bir işaretçi (pointer)
    • Mevcut mesaj sayısını takip eden özel (private) bir tam sayı
    • Maksimum kapasiteyi saklayan özel (private) bir tam sayı
    • Bir kapasite değeri alan ve new[] kullanarak diziyi tahsis eden bir yapıcı (constructor)
    • delete[] kullanarak belleği düzgün bir şekilde serbest bırakan ve "MessageBox destroyed" yazdıran bir yıkıcı (destructor)
    • Yer varsa bir mesaj ekleyen, başarı durumunda true, doluysa false döndüren bir addMessage(string msg) metodu
    • Depolanan her mesajı kendi satırında yazdıran bir printAll() metodu
  • main.cpp: Girişten bir kapasite değeri ve bir mesaj sayısı okuyun. Ardından bu sayı kadar mesaj dizesini okuyun. new kullanarak yığında (heap) bir MessageBox oluşturun, tüm mesajları ona ekleyin, printAll() metodunu çağırın ve ardından belleği serbest bırakmak için MessageBox'ı düzgün bir şekilde silin.

Giriş formatı şu şekilde olacaktır:

  • İlk satır: kapasite (tam sayı)
  • İkinci satır: eklenecek mesaj sayısı (tam sayı)
  • Sonraki satırlar: her satırda bir mesaj

Unutmayın: her new için eşleşen bir delete ve her new[] için eşleşen bir delete[] gereklidir. Sildikten sonra, işaretçileri nullptr olarak ayarlamak iyi bir uygulamadır.

Başlık dosyanızı main.cpp içine #include "MessageBox.h" kullanarak dahil edin.

Kopya kağıdı

Yığın (heap) üzerinde dinamik olarak bellek ayırmak ve bu belleğe bir işaretçi (pointer) almak için new operatörünü kullanın:

int* num = new int;        // Allocate single integer
*num = 42;                 // Assign value through pointer

Player* player = new Player("Hero");  // Allocate object

Belleği serbest bırakmak için her new ifadesinin eşleşen bir delete ifadesi olmalıdır:

delete num;      // Free single object
delete player;   // Calls destructor, then frees memory

Diziler için new[] ve delete[] kullanın:

int* scores = new int[5];    // Allocate array of 5 integers
scores[0] = 100;

delete[] scores;             // Free array - note the brackets!

Kaçınılması gereken yaygın hatalar:

// Memory leak - forgot to delete
int* ptr = new int(10);
ptr = new int(20);    // Lost access to first allocation!

// Dangling pointer - using after delete
delete ptr;
*ptr = 5;             // Undefined behavior!

// Mismatched delete
int* arr = new int[10];
delete arr;           // Wrong! Should be delete[]

Sildikten sonra, yanlışlıkla yeniden kullanımı önlemek için işaretçileri nullptr olarak ayarlayın.

Kendin dene

#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;

int main() {
    int capacity;
    int numMessages;
    
    // Kapasiteyi ve mesaj sayısını oku
    cin >> capacity;
    cin >> numMessages;
    cin.ignore(); // Sayıdan sonraki yeni satır karakterini temizle
    
    // TODO: new kullanarak heap üzerinde bir MessageBox oluştur
    
    // TODO: Tüm mesajları oku ve MessageBox'a ekle
    for (int i = 0; i < numMessages; i++) {
        string message;
        getline(cin, message);
        // Mesajı MessageBox'a ekle
    }
    
    // TODO: Tüm mesajları görüntülemek için printAll() fonksiyonunu çağır
    
    // TODO: Belleği boşaltmak için MessageBox'ı sil
    // Sildikten sonra işaretçiyi nullptr olarak ayarlamayı unutma
    
    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.

Nesne Yönelimli Programlama bölümündeki tüm dersler