C++’da Dinamik Bellek Yönetimi (Dynamic Memory Allocation)

Hazır veri yapıları dersini alıyorken, ders için çalışırken slaytlardan hazırladığım uygulamalara ve aldığım notlara bir anlam katar belki deyip, onları buraya eklemeye başladım. Data structures alanına girmek için ilk olarak dinamik bellek yönetimi konusuna hakim olmak gerekiyor. Zira oluşturacağımız veri türlerinin tamamına yakını dinamik bellek yönetimi sayesinde bilgisayar hafızasını etkili bir yöntemle kullanmış oluyor. Uzun lafın kısası, veri yapılarına girmeden önce bu konu olmazsa olmazlardan.

#include <iostream>

using namespace std;

int add(int a, int b){
    int sum = a + b;
    return sum;
}

void swap(int *x, int *y){
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}

int strUzunluk(char *x){
    int uzunluk = 0;
    while(*(x++)!='\0') uzunluk++; // stringin sonu '\0' ile biter bu da false demek.
    return uzunluk;
}

struct yapi
{
    char isim[20];
    int sayi;
};

int main(int argc, char const *argv[])
{
    int result = add(5, 7); // Varsayılan olarak değer ile çağırılma(call by value) geçerlidir. add

    // Birden fazla değer değiştirmek istersek parametreleri değiştirmemiz gerekir. swap
    int a = 5, b = 6;
    swap(&a, &b); // Değişkenlerin adreslerini gönderiyoruz. Diğer tarafta pointerlar ile alıp bu adreslerde
    // direk değişiklik yapmış olacağız.
    cout << a << " - " << b << endl;

    char ak[] = "Guray yildirim";
    int k = strUzunluk(ak);
    cout << "Adımın uzunluğu: " << k << endl;
    // bir pointer değeri kalıcı olarak değiştirilecekse pointerın pointerı olarak yollanması lazım ki kalıcı olsun.

    /* Dinamik Bellek Yönetimi */
    // Bir pointer a ihtiyaç var. Pointer boş adresi gösterirken işe yaramayacağı için ANLAMLI bellek adresleri gerekir.
    int *p;
    p = new int;
    *p = 5;
    // İşimiz bittiğinde de geri veririz. Geri vermek için:
    delete p; // Bu delete sadece new ile oluşturulanlara etki ediyor.
    // delete yi aynı değişkene birden fazla uygularsak sapıtıyormuş.

    float* dizi;
    dizi = new float [100]; //  100 float alan dizi oluşturulup dizi işaretçisine verildi.
    // Bunu silmek için şöyle yapıyormuşuz:
    delete [] dizi; // Dizi silerken [] kullanıyoruz.

    // heap alınabilecek alanı temsil ediyor, daha doğrusu stack'ın sınırını.
    // Çalışma zamanında stack, heap'i aşarsa stack overflow hatası geliyor.
    // Tersi olursa allocation error geliyor(memory allocation u çok kurcalarsak)

    // SEGMENTATION FAULT HATASI: Memory verilmemişse ya da başlatılmamışsa, ona
    // değer atamaya çalışmak segmentation fault verir.

    yapi gry = {"Güray", 1200};
    yapi g2;
    g2 = gry; // Structlarda eşittir direk tüm içeriği KOPYALAR!
    cout << g2.isim << " - " << g2.sayi << endl;
    g2.sayi = 1000;
    cout << g2.isim << " - " << g2.sayi << endl; // sayı 1000 oldu.
    cout << gry.isim << " - " << gry.sayi << endl; //  gry değişmedi. Yani referans ataması değilmiş.
    // Yapılar fonksiyona komple gönderilir. Burda pointer kullanmak lazım.
    /* NOT: YAPININ ELEMANI OLAN DİZİ FONKSİYONA DEĞERLE GİDER REFERANSLA DEĞİL!!!! */
    // İSMİ CHAR * İLE BELİRLESEK REFERANSI KOPYALARDI.

    // **** Mümkünse iç içe structlar kullan. Kişi ve Özellikleri 2 farklı olsun. OOP gibi. ****

    return 0;
}

Başta da bahsettiğim gibi burda paylaştıklarımın çoğu slaytlardan aldığım notlar. Uygulamaları yaparken de ordan çalıştım. Bu sebeple kaynaklarını da belirtmiş olayım. İTÜ’nün Data Structures dersinde kullanılan slaytlardan çalışarak tuttuğum notları ve kod örneklerini birleştirip yorum satırı şeklinde paylaşıyorum.

 
comments powered by Disqus