Yükleniyor...

Adres ve Bellek Kavramı

Bellekte adresleme, byte düzeni ve göstergelerin temsilini temelden açıklıyor.

C++ dilinde veriler bilgisayarın belleğinde (memory) saklanır. Her değişkenin bellekte kendine ait bir adres (address) konumu vardır. Bellek adreslerini bilmek, pointer (gösterici) gibi güçlü C++ özelliklerini anlamanın temelidir. Bu makalede bellek yapısını, adres kavramını ve değişkenlerin bellekte nasıl tutulduğunu öğreneceğiz.


1. Bellek Nedir?

Bellek (RAM), program çalışırken verilerin ve komutların geçici olarak saklandığı alandır. Program kapandığında bellekteki veriler silinir. C++ derleyicisi değişkenler için bellekten yer ayırır ve bu alanlara adres atar.

Örnek olarak, aşağıdaki kodda her değişkenin bellekte bir adresi vardır:


#include <iostream>
using namespace std;

int main() {
    int yas = 25;
    double pi = 3.14;

    cout << "yas değişkeninin adresi: " << &yas << endl;
    cout << "pi değişkeninin adresi: " << &pi << endl;

    return 0;
}

Çıktı örneği:


yas değişkeninin adresi: 0x61ff0c
pi değişkeninin adresi: 0x61ff08

Her adres, bellekteki fiziksel bir konumu temsil eder ve genellikle **16’lık (hexadecimal)** formatta gösterilir.


2. & (Adres) Operatörü

& operatörü, bir değişkenin adresini verir. Yani değişkenin değerinin bulunduğu bellek konumunu öğrenmemizi sağlar.


int sayi = 100;
cout << "sayi'nin adresi: " << &sayi << endl;
cout << "sayi'nin değeri: " << sayi << endl;

Adres bir konumdur, değer ise o konumda saklanan veridir. Bu ayrım pointer kavramını anlamanın temelidir.


3. Bellek Yapısı (Stack ve Heap)

C++ programı çalışırken bellek genel olarak iki ana bölgeye ayrılır:

BölgeAçıklamaKullanım
Stack (Yığın) Otomatik (yerel) değişkenler burada tutulur. Fonksiyon çağrıldığında alan açılır, fonksiyon bittiğinde temizlenir. Otomatik yaşam döngüsüne sahip değişkenler (int, double vb.)
Heap (Küme) Dinamik olarak ayrılan bellek alanıdır. Programcı tarafından new ve delete ile yönetilir. Dinamik veri yapıları (new ile oluşturulan nesneler)

Örnek:


int x = 10;          // Stack'te saklanır
int *p = new int(5); // Heap'te saklanır

p pointer’ı stack’te tutulur ama gösterdiği veri heap’te yer alır. Bu fark, bellek sızıntılarını (memory leak) önlemek açısından önemlidir.


4. sizeof Operatörü

sizeof operatörü, bir değişkenin veya veri türünün bellekte kaç byte yer kapladığını döndürür.


#include <iostream>
using namespace std;

int main() {
    cout << "int boyutu: " << sizeof(int) << " byte" << endl;
    cout << "double boyutu: " << sizeof(double) << " byte" << endl;
    cout << "char boyutu: " << sizeof(char) << " byte" << endl;
    return 0;
}

Tipik bir sistemde bu değerler şu şekildedir:


5. Bellekte Değişkenlerin Görselleştirilmesi

Örneğin aşağıdaki kodu ele alalım:


int a = 5;
int b = 10;

Bellekte şu şekilde temsil edilir:


Adres       Değer
0x61ff0c → 5   (a)
0x61ff08 → 10  (b)

Her değişkenin adresi farklıdır. Bu adresler bellek sırasına göre artabilir veya azalabilir.


6. Pointer (Gösterici) Kavramına Giriş

Pointer, başka bir değişkenin adresini saklayan özel bir değişkendir. Pointer tanımlamak için * (yıldız) operatörü kullanılır.


#include <iostream>
using namespace std;

int main() {
    int sayi = 42;
    int *ptr = &sayi; // sayi'nin adresi pointer'a atanır

    cout << "sayi değeri: " << sayi << endl;
    cout << "ptr'nin gösterdiği değer: " << *ptr << endl;
    cout << "ptr'nin adresi: " << ptr << endl;

    return 0;
}

Bu örnekte ptr değişkeni bellekteki sayi değişkeninin adresini tutar. *ptr yazıldığında, bu adresin içindeki değere erişilir.


7. Null Pointer ve Güvenli Kullanım

Pointer’lar yanlış adresleri göstermemelidir. Eğer henüz bir adrese atanmadıysa nullptr değeri verilmelidir.


int *p = nullptr;

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

Bu kontrol, runtime hatalarını ve çökme (segmentation fault) sorunlarını önler.


8. Pointer ve Bellek Diyagramı

Aşağıdaki örneği inceleyelim:


int x = 10;
int *p = &x;

Bellek görünümü:


Değişken | Adres     | Değer
x        | 0x61ff0c  | 10
p        | 0x61ff08  | 0x61ff0c

p pointer’ı x’in adresini tutar. *p kullanarak x’in değerine erişebiliriz.


9. Bellek Yönetimi ve Güvenlik

C++’ta belleği doğrudan yönetebilmek büyük bir güç sağlar, ancak bu sorumluluğu da beraberinde getirir. Kullanılmayan dinamik bellek alanları delete ile serbest bırakılmalıdır.


int *p = new int(100); // Heap’te bellek ayır
cout << *p << endl;
delete p;              // Belleği serbest bırak
p = nullptr;           // Asılı (dangling) pointer'ı önle

Bellek sızıntısı (memory leak), serbest bırakılmamış bellek alanlarının zamanla birikmesiyle oluşur ve program performansını düşürür. Bu yüzden her new için bir delete gereklidir.


10. TL;DR

  • Her değişken bellekte bir adrese sahiptir (& operatörüyle alınır).
  • Stack → otomatik, Heap → dinamik bellek alanıdır.
  • sizeof ile türlerin kapladığı alan ölçülebilir.
  • int *p → pointer tanımlar, *p → değere erişir.
  • nullptr → güvenli başlangıç değeri olarak kullanılmalıdır.
  • new ile ayrılan bellek, delete ile serbest bırakılmalıdır.
  • Tüm örnekler Visual Studio 2022 veya GCC 11+ derleyicilerinde çalıştırılabilir.

İlişkili Makaleler