22 Haziran 2015 Pazartesi

C'de Dinamik Bellek Yönetimi - Malloc - Calloc - Realloc

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.

Malloc

En çok kullanılan dby fonksiyonudur.
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 daraltmakamacıyla kullanılır. İçerisine iki parametre alır, birincisi daha önce tahsis edilen bloğun başlangıç adresive 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 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.

Hiç yorum yok:

Yorum Gönder