Dinamik Bellek Yönetimi

Dinamik Bellek Yönetimi, C Programlama Dilinde önem derecesi en yüksek konulardan biri olsa gerek. Bu denli önemli olmasının sebebi sınırsız belleğimimizin olmamasıdır. Sınırsız belleği olan varsa bu yazıyı okumaktan derhal vazgeçebilir. Burada önemli olan belleği verimli kullanabilmektir. Belleği verimli kullanabilmek her programcının amacı olmalıdır. Eğer programcı bellek yönetimini iyi yapamıyorsa daha fazla belleğe ihtiyaç duyar. Daha fazla belleğe ihtiyaç duymak belli başlı birkaç sorunu beraberinde getirir. Fazla maliyet, programın yavaş çalışması bunların en önemlileridir. Yavaş çalışan ve gereğinden fazla bellek tüketen bir programı müşteri niçin kullansın ki ?

Dinamik bellek yönetiminin bir başka yararından bahsedecek olursak, bir dizi tanımlarken

char ad[20];

gibi bir ifade kullandığımızda derleyici bellekten 20 byte boyutunda sürekli bir alan tahsis edecektir. Bu yer tahsisi program başlatılmadan önce yapılmaktadır. Yani programın akışı içerisinde bu dizinin boyutunu değiştirmeniz mümkün değildir. Oysa ki yeri geldiğinde bellekten boyutu sabit olmayan ve sürekli değişebilen yerler tahsis etmemiz gerekecek. Bir örnek vermek gerekirse : bir kütüphaneye gelen ziyaretçilerin listesini tutmak için bellekten tahsis edeceğiniz bölgenin boyutunu önceden tahmin edebilir misiniz ? Tahmin edemeyeceğiniz için her ziyaretçi geldiğinde bellekte ayırdığınız yeri büyüterek belleği en verimli şekilde kullanabilirsiniz. Yani dinamik bellek yönetimi ile programın çalışma zamanı sırasında(Run-Time) -işletim sistemine danışarak- sürekli bellek bölgeleri tahsis edebiliriz.

Dinamik Bellek Yönetimi Fonksiyonları

Standart olarak

  • Malloc
  • Calloc
  • Realloc
  • Free

fonksiyonları en çok kullanılan dby(dinamik bellek yönetimi) fonksiyonlarıdır. Bunların dışında sistem bağımlı dby fonksiyonlarıda bulunmaktadır. Fakat onlar hakkında bilgim olmadığından dolayı burada bahsedemeyeceğim.

Malloc

En çok kullanılan dby fonksiyonudur. Bu fonksiyonun tanımı STDLIB.H kütüphanesinin içinde yapıldığından programınızı başına bu kütüphaneyi eklemelisiniz. Fakat Microsoft‘un derleyicilerinde MALLOC.H kütüphanesinde de bulunmaktadır.

#include <stdlib.h>

Malloc fonksiyonu programın çalışma zamanı sırasında (Run-Time) belleğin güvenli bir bölgesinden istenilen uzunluk kadar yer tahsis etmektedir. Geriye bir değer döndürür ve bu değer ayırdığı bellek bölgesinin başlangıç adresine işaret etmektedir. Eğer bellekten tahsisat yapamazsa geriye 0 değerini döndürür.

char *p;
p = malloc(5);

Bu ifade ile bellekte 5 byte boyutunda sürekli bir alan tahsis edilecektir ve tahsis edilen alanın başlangıç adresi p pointerına atanacaktır.

Bellekten yer ayırma işleminin başarısını kontrol etmek isterseniz aşağıdaki gibi bir yol izleyebilirsiniz.

char *p;
p = malloc(5);
if(p) printf("Tahsisat Basarili !\n");
else printf("Tahsisat Yapilamadi\n");

Burada 5 değeri yerine 99999999999999 değerini vererek yer ayrılmama durumunu da test edebilirsiniz.

Yukarıdaki örnekte pointerın tipi char olduğundan dolayı 5 elamanlı bir char bloğu ayrılmıştır fakat char yerine int kullanırsak biraz daha farklı bir senaryo olmakta :

int *p;
p = malloc(20);

Burada int tipinden 5 elemanlık bir blok tahsis edilmektedir. Bunun sebebi int veri tipinin 32 bit sistemlerde 4 byte yer kaplamasıdır. Fakat 16 bit sistemlerde veya 64 bit sistemlerde 5 elemanlı bir blok yerine 10 elemanlık veya 2 elemanlık bloklar ayrılabilir. Bunu engellemek için sizeof fonksiyonunu kullanabiliriz. Aşağıdaki örnekte bellekten ayrılan yer bütün sistemlerde 5 elemanlık bir blok olacaktır.

int *p;
p = malloc(sizeof(int)*5);

Malloc fonksiyonunun geriye bir adres döndürdüğünü söylemiştim. Bu noktada oluşturduğumuz pointerın tipi ile geriye döndürdüğümüz adresin tipinin aynı olmasına özen gösterin, yoksa derleyici uyarı verebiliyor. Eğer bilinçli bir tür dönüşümü yapmak isterseniz şu kodlar işinize yarayacaktır.

int *p;
p = (int *)malloc(sizeof(int)*5);

Bu ifade ile hem kendinizi güvene almış olursunuz hem de kodun okunurluluğunu arttırmış olursunuz.

Malloc fonksiyonu tahsis ettiği bellekteki bölgelere herhangi bir ilkdeğer atama işlemi uygulamaz. Yani bellekteki değerleri ile beraber size tahsis eder, ilkdeğer atamak size kalmış bir iştir.

Calloc

Malloc fonksiyonuna oldukça benzer bir yapısı vardır. Calloc fonksiyonu içerisine 2 parametre alır, birinci parametresiyle ikinci parametresinin çarpımı kadar (byte) bellek bölgesi ayırır. 15 elemanlı int tipinden bir blok ayırmak için aşağıdaki kodlar yeterli olacaktır.

int *p;
p = calloc(15,sizeof(int));

Calloc fonksiyonu aslında bellek tahsisatı yaparken Malloc fonksiyonunu kullanıyormuş bunu da küçük bir not olarak ekliyim.

Calloc, malloctan farklı olarak ayırdığı bellek bölgesini sıfırlamaktadır. Sıfırlama işlemini bizim için kendisi yapıyor. Aşağıdaki iki örneği inceleyiniz, ikiside bellekten 15 elemanlı bir int blok dizisi tahsis edip içini sıfırlıyor ve içeriğini ekrana basıyor.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main() {
   int *p,i;
   p = malloc(sizeof(int)*15);
   for(i=0;i<15;i++) {
      p[i]=0;
      printf("Ayrilan Bolgenin %d. Elemani ---> %d\n",i+1,p[i]);
   }
   getch();
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h> 
int main() {
   int *p,i;
   p = calloc(15,sizeof(int));
   for(i=0;i<15;i++) {
      printf("Ayrilan Bolgenin %d. Elemani ---> %d\n",i+1,p[i]);
   }
   getch();
}

Realloc

Realloc fonksiyonu daha önce malloc veya calloc ile yapılmış tahsisatı genişletmek ya da daraltmak amacıyla kullanılır. İçerisine iki parametre alır, birincisi daha önce tahsis edilen bloğun başlangıç adresi ve ikincisi ise bloğun yeni uzunluğudur.

Realloc fonksiyonu yeni tahsisatı yaparken eğer belleğin daha önce tahsis edilmiş bloğunun yanında yer yoksa, bloğun tamamını içerikleriyle birlikte yeterli uzunluğu olan bir bölgeye taşır. Bu sebepten dolayı geriye döndürdüğü adres pointerı, daha önce malloc ya da calloc ile kullanılan adres pointerı ile aynı olmalıdır. Aşağıdaki örnekte önce 15 elemanlı bir int blok dizisi ayrılmış ve sonra realloc fonksiyonu ile 20 elemana genişletilmiştir.

int *p;
p = calloc(15,sizeof(int));   
p = realloc(p,sizeof(int)*5);

Eğer realloc bloğu genişletemezse geriye 0 değerini döndürecektir.

Bu arada realloc fonksiyonunu kullanmak için daha önce malloc ya da calloc fonksiyonunu kullanmış olmanız gerektiğini unutmayın.

Realloc fonksiyonu da malloc fonksiyonu gibi tahsis ettiği bloğa ilk değer vermez.

Yazının en başında verimli bellek yönetiminden bahsetmiştim. Bu fonksiyon ile ayırdığınız bellek bölgesini küçülttüğünüzde bloğunuz bellekte yer değiştirmiş olabilir, biraz mantıksız gelebilir ama olayın aslı çok mantıklıdır. Küçültülen bellek bölgesi, bellekte daha uygun bir yere taşındığında, meslea tam ona uygun bir uzunluktaki boşluğa taşındığında belleği tam olarak verimli kullanmış olmaz mısınız ?

Free

Free fonksiyonu verimli ve dinamik bellek kullanmayı sağlayan en önemli fonksiyonlardandır. Bu fonksiyon ile malloc ya da calloc ile daha önceden ayırdığınız bellek bölgelerini işletim sistemine geri iade edebilirsiniz. Parametre olarak içine daha önce ayırdığınız bellek bölgesinin başlangıç adresini göndermelisiniz.

int *p;
p = malloc(sizeof(int)*25);
free(p);

Eğer tahsis edilmiş bellek bölgesi free fonksiyonu ile geri iade edilmemişse, programın sonunda otomatik olarak boşaltılır.

Dinamil bellek yönetimi ile iligli olarak benim bildiklerim bu kadardı. Eğer eklemek istediğiniz ya da düzeltmek istediğiniz yerler varsa aşağıdaki yorum bölümünü kullanabilirsiniz.

Benzer Yazılar

Yorumlar

  • buğra şen , 02 Aralık 2012 - 22:44:22

    mesela 2 boyutlu dizileri (matris gibi)dinamik olarak açıp boşaltmak istersek ne yapmamız gerekir ?

    Cevapla
    • Cem Demir , 03 Aralık 2012 - 01:11:31

      İşin içine malloc ve calloc girince iki boyutlu veya daha fazla boyutlu kavramı tamamen programcıya kalıyor.

      Mesela matris[3][3] gibi bir tanım ile programa iki boyutlu bir dizi oluştur diyebilirsin ama malloc ile bir bellek alanı tahsis ediyorsan, elde edeceğin bellek düz bir alan olacaktır. Bu alanı alıp dizi gibi kullanmak sana düşen kısım.

      Esasında 2 boyutlu bir dizi oluşturduğunda da aynı şey yapılıyor, düz bir alana dizi oluşturuluyor ama arkaplanda ne olduğunu bilmen gerekmiyor. Dinamik bellek tahsis yaptığında arkaplanda olan olayları yönetmen gerektiği için o bellek alanını alıp dizi şekline getirmen gerekiyor.

      Cevapla
  • ali , 02 Haziran 2013 - 04:05:45

    emeğine sağlık kardeş

    Cevapla
  • Tuna SÖNMEZ , 28 Ekim 2013 - 19:51:52

    Çok açıklayıcı olmuş..Teşekkürler..

    Cevapla
  • murat , 03 Nisan 2014 - 10:27:23

    Çok teşekkürler , gerçekten anlaşılır olmuş. Araştırmalarımdan sonra bu konuyu bu kadar açıklayıcıolarak bulmama şaşırdım

    Cevapla
  • Mehmet , 23 Mart 2015 - 22:53:32

    Sağolasın hocam anlatım güzel olmuş.

    Cevapla
  • berfin , 25 Ekim 2015 - 14:52:12

    foksiyona dinamik matris yollarken mainde bu foksiyonu yazarken nasil yazariz(& kullanimi) mesela function( i, &ptr) o adresli kisim nasil olabilir)
    cevaplarsaniz memnun olurum..

    Cevapla
  • Mustafa , 19 Aralık 2015 - 16:08:31

    int *p;
    p = calloc(15,sizeof(int));
    p = realloc(p,sizeof(int)*5);
    reallocun örneğindeki 5’in 20 olması gerekirdi.
    Ellerinize sağlık güzel anlatım

    Cevapla
  • Abdullah KELEŞ , 13 Ocak 2016 - 16:05:13

    Elinize sağlık çok yararlı oldu

    Cevapla
  • Baran Karaoguz , 16 Mart 2016 - 01:42:48

    Komut satırından girilen tam sayı dizi elemanları üzerinde işlem yapan ve yine komut satırından belirtilen parametreye göre toplayan veya çarpan programı aşagıdaki gibi yazınız.İşlem türü belirtilmediği veya hatayı söylesin..

    Örnek:

    ./program -t 2 3 4 5
    toplam = 14

    ./program -c 2 3 4
    carpım 24

    ./program -p 2 3 4
    geçersiz giriş..

    Hocam tam olarak fasafiso kısmını anlatmanıza gerek benim istedigim kullanıcının for dongusunde girdigi kac tane karakter oldugunu tutmasını ve bunu dinamik dizinin boyutu yapmasını istiyorum yardımcı olabilirmisiniz?

    Cevapla
  • muhammet furkan çiftçi , 07 Mayıs 2016 - 10:21:20

    çok temiz akıcı bir anlatım olmuş gerçekten, çok iş gördü Allah senden razı olsun birader

    Cevapla

Yorum Yazın

Su elementleri kullanabilirsiniz : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Arama
RSS
Beni yukari isinla