C Programlama Dili'ne Giriş

  Dersler
* Önsöz

* Giriş
* Veri Tipleri, Değişkenler
* Operatörler
* Temel G/Ç Fonksiyonları
* Temel Kütüphane Fonksiyonları
* Karşılaştırma Deyimleri
* Döngüler
* Fonksiyonlar I
* Fonksiyonlar II
* Diziler
* Gösterici (Pointer) Kavramı
* Katarlar (Stringler)
* Dinamik Bellek Yönetimi
* Gösterici Uygulamaları
* Yapılar ve Birlikler
* Dosya Yönetimi
* Bit Düzeyinde Çalışmak
* Port Denetimi
* Grafik Kullanımı
* C Makroları

* Kısaca C++
* Derleme Seçenekleri
* Tarih-Saat Fonksiyonları
* Monte-Carlo Yöntemleri
* Fortran ve C

* Yararlanılan Kaynaklar

  C/C++ Derleyicileri
* Dev-C++
* Salford (silversoft FTN95)
* GCC
* Turbo C
* Eclipse IDE
* NetBeans IDE

  Dış Bağlantılar
* programlama.com
* C Programcıları Derneği

* C (wikipedia)
* C++ (wikipedia)
* cplusplus.com
* koders.com
* Hot scripts

 

Ders 13: Dinamik Bellek Yönetimi

################---- (%80)

En son güncelleme: Wed, 30 Nov 2011 13:22:02 +0200

Giriş

Bir C programı içerisinde, dizilerin boyutu ve kaç elemanlı olduğu program başında belirtilirse, derleyici o dizi için gereken bellek alanını (bölgesini) program sonlanıncaya kadar saklı tutar ve bu alan başka bir amaç için kullanılamaz [1]. Bu türden diziler statik dizi olarak isimlendirilir. Statik dizinin boyutu programın çalışması esnasında (run time) değiştirilemez.

Fakat, programın çalışırken bir dizinin boyutu ve eleman sayısı bazı yöntemler kullanılarak değiştirilebilir. Bu tür dizilere dinamik dizi denir. Dinamik diziler için gereken bellek bölgesi, derleyici tarafından işletim sisteminden istenir, kullanılır ve daha sonra istenirse bu bölge boşaltırılır. Bu bölümde, dinamik dizi kavramı ve dinamik bellek yönetimi anlatılacaktır.


13.1   Dinamik Dizi Fonksiyonları

ANSI C'de, dinamik diziler işaretçi kullanılarak ve standart kütüphanedeki malloc(), calloc(), realloc() ve free() fonksiyonlarının yardımıyla ile oluşturulur veya boşaltılır. Bu fonksiyonlar Tablo 13.1 de listelenmiştir.

Tablo 13.1: stdlib.h kütüphanesindeki dinamik bellek fonksiyonları
Dinamik Bellek Fonksiyonu Açıklama
void *malloc(size_t eleman_sayısı); Bellekte herbiri size_t tipinde olan eleman_sayısı kadar yer (bellek bloğu) ayırır. Bu yer verilmezse geriye NULL gönderir.
void *calloc(size_t eleman_sayısı, size_t nbayt); Bellekte herbiri nbayt kadar yer işgal edecek eleman_sayısı kadar boş yer ayırır ve bütün bitleri sıfırlar. Bu yer ayrılamazsa geriye NULL gönderir.
void *realloc(void *ptr, size_t nbayt); ptr işaretçisi ile gösterilen bellek bloğunu, nbayt kadar büyüterek veya küçülterek değiştirir. Bu iş gerçekleşmezse geriye NULL gönderir.
void free(void *ptr); Daha önce ayrılan adresi ptr'de saklanan bellek alanının boşaltır.

Tamsayı tipinde bir dinamik dizi tanımlanırken aşağıdaki işlem basamakları izlenmelidir:

      /* dinamik dizi bildirimi */
      int *dizi;

      /* eleman saysını belirle */
      scanf("%d",&n);

     /* n tane bellek bloğu isteniyor */
     dizi = (int *) malloc( sizeof(int)*n ); 

     /* Boş yer varmı sorgulanıyor */
     if( dizi == NULL )
        printf("Yetersiz bellek alanı\n"), exit(1);
 
     ...
     /* dizi burada kullanılıyor */
     ...

     /* bellek bloğu boşaltılıyor */
     free(dizi);  

Program 13.1, eleman sayısı klavyeden girilen bir dizinin aritmetik ortalamasını hesaplar. Eleman sayısı sıfır veya negatif bir değer olduğunda, sonsuz döngüden çıkılır ve program sonlanır. İnceleyiniz.

Program 13.1: Dinamik dizi ile ortalama hesabı
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
/* 13prg01.c: Dinamik dizi ile ortalama hesabı */

#include <stdio.h>
#include <stdlib.h>

int main(){

  int n,i;
  float *x, toplam, ort;

  while(1)
  {
        /* dizinin eleman sayısı okunuyor */
        printf("\nEleman sayısını girin: ");
        scanf("%d",&n);

        /* eleman sayısı <= 0 ise dögüden çık */
        if( n<=0 )
          break;

        /* bellekten yer isteniyor */
        x = (float *)  malloc( sizeof(float)*n );

       /* istenen yer ayrıldı mı? */
       if( x == NULL ){
         puts("Yetersiz bellek alanı");
         exit(1);
       }

       /* elemanlar tek tek belleğe yazılıp toplamları hesaplanıyor */
       for(toplam =0.0, i=0; i<n; i++){
          printf("%d. eleman: ",i+1);
          scanf("%f",&x[i]);
          toplam += x[i];
       }

       ort = toplam / n;

       printf("Ortalama = %f\n",ort);

       /* ayrılan alan boşaltılıyor */
       free(x);
  }

 return 0;
}

ÇIKTI

Eleman sayısını girin: 2
1. eleman: 4
2. eleman: 6
Ortalama = 5.000000

Eleman sayısını girin: 4
1. eleman: 2
2. eleman: 3
3. eleman: 1
4. eleman: 5
Ortalama = 2.750000

Eleman sayısını girin: 0

Karakter dizileri içinde benzer adımlar uygulanır. Program 13.2'de tanımlanan altKatar() fonksiyonu, bir katarın alt parçalarını geri döndürür.

Program 13.2: Bir karakter dizisinin alt parçalarının bulunması
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
/* 13prg02.c: Bir katarın parçalarini (alt katar) veren fonksiyon */

#include <stdio.h>
#include <stdlib.h>

char *altKatar(char *str, int, int);

int main()
{
   int  i;
   char *s, *parca;

   s = "programlama";

   for(i=0; s[i]; i++)
   {
      parca = altKatar(s, 0, i);
      puts(parca);
   }

 return 0;
}

/* str'nin p1. elemanindan p2. elemanina kadar olan alt katarını gonderir. */
char *altKatar(char *str, int p1, int p2)
{  
   int i, j=0, n;
   static char *alt;
   n = p2 - p1;
 
   /* bellekten yer ayrılıyor... */
   alt = (char *) malloc( n*sizeof(char) );

   for(i=p1; i<=p2; i++)
     alt[j++] = str[i];

   return alt;
}

ÇIKTI

p
pr
pro
prog
progr
progra
program
programl
programla
programlam
programlama


13.2   Dinamik Matrisler

İki veya daha fazla boyuta sahip dinamik dizi oluşturmak mümkündür. Bu durumda, göstericiyi gösteren göstericler kullanılır. Program 13.3, bir matrisin elemanları bulup ekrana yazar.

Program 13.3: Dinamik matris tanımlama
01: 
02: 
03: 
04: 
05: 
06: 
07: 
08: 
09: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
/* 13prg02.c: Dinamik matris tanımlama */

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int **matris;
    int satir, kolon;
    int s, k;
    int i;

    printf("Matrisin satır sayısı: ");
    scanf("%d", &satir);

    printf("Matrisin kolon sayısı: ");
    scanf("%d", &kolon);

    /* dıştaki dizi için bellek alanı isteniyor  */
    matris = (int **) calloc(satir, sizeof(int));

    /* içteki dizi için bellek alanı isteniyor */
    for(i = 0; i < satir; i++)
	matris[i] = (int *) calloc(kolon, sizeof(int));

    /* matrisin elemanları okunuyor */
    for(s = 0; s < satir; s++)
	for(k = 0; k < kolon; k++) {
	    printf("Matrisin elemanı girin: matris[%d][%d] = ", s, k);
	    scanf("%d", &(matris[s][k]));
        }

    printf("\nGirilen matris:\n");

    for(s = 0; s < satir; s++) {
	for(k = 0; k < kolon; k++)
	    printf("%4d", matris[s][k]);

        printf("\n");
    }

    /* içteki dizi boşaltılıyor */
    for(i = 0; i < satir; i++)
	free((void *) matris[i]);

    /* dıştaki dizi boşaltılıyor */
    free((void *) matris);

    return(0);
}

ÇIKTI

Matrisin satır sayısı: 2
Matrisin kolon sayısı: 3
Matrisin elemanı girin: matris[0][0] = 1
Matrisin elemanı girin: matris[0][1] = 2
Matrisin elemanı girin: matris[0][2] = 3
Matrisin elemanı girin: matris[1][0] = 5
Matrisin elemanı girin: matris[1][1] = 6
Matrisin elemanı girin: matris[1][2] = 8

Girilen matris:
   1   2   3
   5   6   8



Powered by PHP