- Puan
- 28
- Yaş
- 118
╔════════════════════════════════════════════════════════════════════╗
║ C PROGRAMLAMA DİLİ EĞİTİM SERİSİ #10 ║
║ DİNAMİK BELLEK YÖNETİMİ ║
║ malloc(), calloc(), realloc(), free() ║
║ (Mala Anlatır Gibi) ║
╚════════════════════════════════════════════════════════════════════╝
Önceki bölümde Pointerları öğrendik.
Şimdi C dilinin en güçlü konularından birine geldik.
Dinamik Bellek Yönetimi.
Bu konuyu öğrenmeden:
✓ Oyun motorları
✓ İşletim sistemleri
✓ Ağ araçları
✓ Reverse Engineering
✓ Malware Analizi
✓ Gömülü Sistemler
gibi alanlarda ilerlemek çok zordur.
Bu bölümü iyice anlamaya çalış.
Çünkü profesyonel C programlarının çoğu bu mantık üzerine kuruludur.
════════════════════════════════════════════════════════════════════
▓▓▓ PROBLEM NEREDE?
Örnek:
int sayilar[100];
Burada ne yaptık?
100 elemanlık yer ayırdık.
Peki kullanıcı kaç sayı girecek?
Bilmiyoruz.
Belki:
5
Belki:
500
Belki:
5000
Biz programı yazarken bunu bilemeyiz.
İşte burada dinamik bellek devreye girer.
════════════════════════════════════════════════════════════════════
▓▓▓ STATİK BELLEK NEDİR?
Şimdiye kadar kullandığımız:
int sayilar[100];
char isim[50];
gibi tanımların tamamı statiktir.
Program çalışmadan önce boyut bellidir.
Avantaj:
✓ Hızlıdır
✓ Basittir
Dezavantaj:
✗ Esnek değildir
════════════════════════════════════════════════════════════════════
▓▓▓ DİNAMİK BELLEK NEDİR?
Program çalışırken ihtiyaç kadar bellek ayırmaktır.
Örnek:
Kullanıcı:
10 eleman
isterse 10
1000 eleman isterse 1000
ayırabiliriz.
════════════════════════════════════════════════════════════════════
▓▓▓ HEAP NEDİR?
Programın kullandığı bellek bölümleri vardır.
Stack
Heap
Data
Text
gibi.
Bugün bizi ilgilendiren:
HEAP
bölgesidir.
malloc ve arkadaşları burada çalışır.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC NEDİR?
malloc:
Memory Allocation
kelimelerinden gelir.
Görevi:
Bellekten yer ayırmak.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC KULLANIMI
Örnek:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = malloc(sizeof(int));
*ptr = 50;
printf("%d", *ptr);
free(ptr);
return 0;
}
ÇIKTI
50
════════════════════════════════════════════════════════════════════
▓▓▓ sizeof() NEDİR?
Örnek:
sizeof(int)
int veri tipinin kaç byte olduğunu verir.
Çoğu sistemde:
4 byte
çıktısı alınır.
Örnek:
printf("%d", sizeof(int));
ÇIKTI
4
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC NASIL ÇALIŞIYOR?
Örnek:
ptr = malloc(sizeof(int));
Bilgisayar diyor ki:
"Heap'te bir int kadar yer ayır."
Sonra adres döndürüyor.
Pointer da bu adresi tutuyor.
Şema:
Heap
1000 → Boş Alan
malloc
↓
ptr = 1000
════════════════════════════════════════════════════════════════════
▓▓▓ DİZİ İÇİN MALLOC
Örnek:
int *sayilar;
sayilar = malloc(5 * sizeof(int));
Bellekte:
5 adet int
için yer ayrılır.
Artık:
sayilar[0]
sayilar[1]
sayilar[2]
sayilar[3]
sayilar[4]
kullanılabilir.
════════════════════════════════════════════════════════════════════
▓▓▓ ÖRNEK
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *sayilar;
sayilar = malloc(5 * sizeof(int));
for(int i=0;i<5;i++)
{
sayilar = i+1;
}
for(int i=0;i<5;i++)
{
printf("%d\n", sayilar);
}
free(sayilar);
return 0;
}
ÇIKTI
1
2
3
4
5
════════════════════════════════════════════════════════════════════
▓▓▓ FREE NEDİR?
En önemli fonksiyonlardan biridir.
malloc ile alınan belleği geri verir.
Örnek:
free(ptr);
Bunu yapmazsan:
Bellek sızıntısı oluşur.
════════════════════════════════════════════════════════════════════
▓▓▓ MEMORY LEAK NEDİR?
Bellek ayırıp geri vermemektir.
Örnek:
int *ptr;
ptr = malloc(sizeof(int));
Program çalışıyor...
Ama:
free(ptr);
yok.
Sonuç:
Bellek boşa işgal edilir.
Uzun süre çalışan programlarda büyük problem oluşturur.
════════════════════════════════════════════════════════════════════
▓▓▓ CALLOC NEDİR?
calloc:
Contiguous Allocation
anlamına gelir.
malloc'a benzer.
Ama ekstra bir özelliği vardır.
Belleği sıfırlar.
════════════════════════════════════════════════════════════════════
▓▓▓ CALLOC KULLANIMI
int *ptr;
ptr = calloc(5,sizeof(int));
Bellekte:
0
0
0
0
0
oluşturur.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC VE CALLOC FARKI
malloc:
Çöp veri içerebilir.
Örnek:
1254
998
412
...
calloc:
0
0
0
0
0
ile başlar.
════════════════════════════════════════════════════════════════════
▓▓▓ REALLOC NEDİR?
Daha önce ayrılmış belleğin boyutunu değiştirir.
Örnek:
Başta:
5 eleman
ayırdık.
Sonra:
50 eleman
gerekti.
Tekrar malloc yapmak yerine:
realloc
kullanılır.
════════════════════════════════════════════════════════════════════
▓▓▓ REALLOC KULLANIMI
int *ptr;
ptr = malloc(5 * sizeof(int));
ptr = realloc(ptr,10*sizeof(int));
Artık:
10 elemanlık
yerimiz vardır.
════════════════════════════════════════════════════════════════════
▓▓▓ GERÇEK HAYAT ÖRNEĞİ
Bir forum düşün.
İlk başta:
100 kullanıcı
bekleniyor.
Sonra:
50000 kişi geldi.
Program belleği büyütebilir.
İşte realloc tam bunun için vardır.
════════════════════════════════════════════════════════════════════
▓▓▓ NULL KONTROLÜ
malloc başarısız olabilir.
Bu yüzden:
int *ptr;
ptr = malloc(sizeof(int));
if(ptr == NULL)
{
printf("Bellek Ayrilamadi");
}
şeklinde kontrol etmek gerekir.
Profesyonel kodlarda bu zorunludur.
════════════════════════════════════════════════════════════════════
▓▓▓ DİNAMİK DİZİ
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
printf("Kac eleman: ");
scanf("%d",&n);
int *sayilar;
sayilar = malloc(n*sizeof(int));
for(int i=0;i<n;i++)
{
scanf("%d",&sayilar);
}
for(int i=0;i<n;i++)
{
printf("%d\n",sayilar);
}
free(sayilar);
return 0;
}
Artık kullanıcı kaç eleman isterse o kadar yer ayrılır.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC İLE STRING
char *isim;
isim = malloc(50*sizeof(char));
Artık:
50 karakterlik
alan ayrılmıştır.
════════════════════════════════════════════════════════════════════
▓▓▓ POINTER + MALLOC
Aslında:
malloc
daima adres döndürür.
Bu yüzden:
Pointer olmadan kullanılamaz.
Örnek:
int *ptr;
ptr = malloc(sizeof(int));
Tamamen pointer mantığıyla çalışır.
════════════════════════════════════════════════════════════════════
▓▓▓ MİNİ PROJE #1
KULLANICI KADAR SAYI ALMA
#include <stdio.h>
#include <stdlib.h>
int main()
{
int adet;
scanf("%d",&adet);
int *sayilar;
sayilar = malloc(adet*sizeof(int));
for(int i=0;i<adet;i++)
{
scanf("%d",&sayilar);
}
for(int i=0;i<adet;i++)
{
printf("%d\n",sayilar);
}
free(sayilar);
return 0;
}
════════════════════════════════════════════════════════════════════
▓▓▓ MİNİ PROJE #2
ORTALAMA HESAPLAMA
int n;
scanf("%d",&n);
int *notlar;
notlar = malloc(n*sizeof(int));
int toplam = 0;
for(int i=0;i<n;i++)
{
scanf("%d",¬lar);
toplam += notlar;
}
printf("%d", toplam/n);
free(notlar);
════════════════════════════════════════════════════════════════════
▓▓▓ MİNİ PROJE #3
REALLOC İLE BÜYÜTME
int *ptr;
ptr = malloc(5*sizeof(int));
ptr = realloc(ptr,20*sizeof(int));
free(ptr);
Başlangıç:
5 eleman
Sonra:
20 eleman
════════════════════════════════════════════════════════════════════
⚠ YENİ BAŞLAYANLARIN HATALARI
HATA #1
malloc kullanıp free kullanmamak.
Memory Leak oluşur.
════════════════════════════════════════════════════════════════════
HATA #2
malloc sonrası NULL kontrolü yapmamak.
════════════════════════════════════════════════════════════════════
HATA #3
free edilen pointerı kullanmaya devam etmek.
Örnek:
free(ptr);
printf("%d",*ptr);
Çok tehlikelidir.
════════════════════════════════════════════════════════════════════
HATA #4
Yanlış boyut hesaplamak.
Örnek:
malloc(10);
yerine:
malloc(10*sizeof(int));
kullanılmalıdır.
════════════════════════════════════════════════════════════════════
HATA #5
Bir pointerı iki kez free etmek.
Bu ciddi program hatalarına yol açabilir.
════════════════════════════════════════════════════════════════════
▓▓▓ PROFESYONEL İPUCU
free yaptıktan sonra:
ptr = NULL;
atanması tavsiye edilir.
Örnek:
free(ptr);
ptr = NULL;
Böylece yanlışlıkla kullanma riski azalır.
════════════════════════════════════════════════════════════════════
✓ BÖLÜM ÖZETİ
Bu bölümde:
✓ Heap kavramı
✓ Dinamik bellek
✓ malloc()
✓ calloc()
✓ realloc()
✓ free()
✓ Memory Leak
✓ NULL kontrolü
✓ Dinamik diziler
✓ Dinamik stringler
✓ Pointer ilişkisi
✓ Profesyonel kullanım kuralları
konularını öğrendik.
Bir sonraki bölümde STRUCT (Yapılar) konusuna geçeceğiz. Bu bölümden sonra artık gerçek uygulamalar geliştirmeye başlayabileceğiz.
║ C PROGRAMLAMA DİLİ EĞİTİM SERİSİ #10 ║
║ DİNAMİK BELLEK YÖNETİMİ ║
║ malloc(), calloc(), realloc(), free() ║
║ (Mala Anlatır Gibi) ║
╚════════════════════════════════════════════════════════════════════╝
Önceki bölümde Pointerları öğrendik.
Şimdi C dilinin en güçlü konularından birine geldik.
Dinamik Bellek Yönetimi.
Bu konuyu öğrenmeden:
✓ Oyun motorları
✓ İşletim sistemleri
✓ Ağ araçları
✓ Reverse Engineering
✓ Malware Analizi
✓ Gömülü Sistemler
gibi alanlarda ilerlemek çok zordur.
Bu bölümü iyice anlamaya çalış.
Çünkü profesyonel C programlarının çoğu bu mantık üzerine kuruludur.
════════════════════════════════════════════════════════════════════
▓▓▓ PROBLEM NEREDE?
Örnek:
int sayilar[100];
Burada ne yaptık?
100 elemanlık yer ayırdık.
Peki kullanıcı kaç sayı girecek?
Bilmiyoruz.
Belki:
5
Belki:
500
Belki:
5000
Biz programı yazarken bunu bilemeyiz.
İşte burada dinamik bellek devreye girer.
════════════════════════════════════════════════════════════════════
▓▓▓ STATİK BELLEK NEDİR?
Şimdiye kadar kullandığımız:
int sayilar[100];
char isim[50];
gibi tanımların tamamı statiktir.
Program çalışmadan önce boyut bellidir.
Avantaj:
✓ Hızlıdır
✓ Basittir
Dezavantaj:
✗ Esnek değildir
════════════════════════════════════════════════════════════════════
▓▓▓ DİNAMİK BELLEK NEDİR?
Program çalışırken ihtiyaç kadar bellek ayırmaktır.
Örnek:
Kullanıcı:
10 eleman
isterse 10
1000 eleman isterse 1000
ayırabiliriz.
════════════════════════════════════════════════════════════════════
▓▓▓ HEAP NEDİR?
Programın kullandığı bellek bölümleri vardır.
Stack
Heap
Data
Text
gibi.
Bugün bizi ilgilendiren:
HEAP
bölgesidir.
malloc ve arkadaşları burada çalışır.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC NEDİR?
malloc:
Memory Allocation
kelimelerinden gelir.
Görevi:
Bellekten yer ayırmak.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC KULLANIMI
Örnek:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = malloc(sizeof(int));
*ptr = 50;
printf("%d", *ptr);
free(ptr);
return 0;
}
ÇIKTI
50
════════════════════════════════════════════════════════════════════
▓▓▓ sizeof() NEDİR?
Örnek:
sizeof(int)
int veri tipinin kaç byte olduğunu verir.
Çoğu sistemde:
4 byte
çıktısı alınır.
Örnek:
printf("%d", sizeof(int));
ÇIKTI
4
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC NASIL ÇALIŞIYOR?
Örnek:
ptr = malloc(sizeof(int));
Bilgisayar diyor ki:
"Heap'te bir int kadar yer ayır."
Sonra adres döndürüyor.
Pointer da bu adresi tutuyor.
Şema:
Heap
1000 → Boş Alan
malloc
↓
ptr = 1000
════════════════════════════════════════════════════════════════════
▓▓▓ DİZİ İÇİN MALLOC
Örnek:
int *sayilar;
sayilar = malloc(5 * sizeof(int));
Bellekte:
5 adet int
için yer ayrılır.
Artık:
sayilar[0]
sayilar[1]
sayilar[2]
sayilar[3]
sayilar[4]
kullanılabilir.
════════════════════════════════════════════════════════════════════
▓▓▓ ÖRNEK
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *sayilar;
sayilar = malloc(5 * sizeof(int));
for(int i=0;i<5;i++)
{
sayilar = i+1;
}
for(int i=0;i<5;i++)
{
printf("%d\n", sayilar);
}
free(sayilar);
return 0;
}
ÇIKTI
1
2
3
4
5
════════════════════════════════════════════════════════════════════
▓▓▓ FREE NEDİR?
En önemli fonksiyonlardan biridir.
malloc ile alınan belleği geri verir.
Örnek:
free(ptr);
Bunu yapmazsan:
Bellek sızıntısı oluşur.
════════════════════════════════════════════════════════════════════
▓▓▓ MEMORY LEAK NEDİR?
Bellek ayırıp geri vermemektir.
Örnek:
int *ptr;
ptr = malloc(sizeof(int));
Program çalışıyor...
Ama:
free(ptr);
yok.
Sonuç:
Bellek boşa işgal edilir.
Uzun süre çalışan programlarda büyük problem oluşturur.
════════════════════════════════════════════════════════════════════
▓▓▓ CALLOC NEDİR?
calloc:
Contiguous Allocation
anlamına gelir.
malloc'a benzer.
Ama ekstra bir özelliği vardır.
Belleği sıfırlar.
════════════════════════════════════════════════════════════════════
▓▓▓ CALLOC KULLANIMI
int *ptr;
ptr = calloc(5,sizeof(int));
Bellekte:
0
0
0
0
0
oluşturur.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC VE CALLOC FARKI
malloc:
Çöp veri içerebilir.
Örnek:
1254
998
412
...
calloc:
0
0
0
0
0
ile başlar.
════════════════════════════════════════════════════════════════════
▓▓▓ REALLOC NEDİR?
Daha önce ayrılmış belleğin boyutunu değiştirir.
Örnek:
Başta:
5 eleman
ayırdık.
Sonra:
50 eleman
gerekti.
Tekrar malloc yapmak yerine:
realloc
kullanılır.
════════════════════════════════════════════════════════════════════
▓▓▓ REALLOC KULLANIMI
int *ptr;
ptr = malloc(5 * sizeof(int));
ptr = realloc(ptr,10*sizeof(int));
Artık:
10 elemanlık
yerimiz vardır.
════════════════════════════════════════════════════════════════════
▓▓▓ GERÇEK HAYAT ÖRNEĞİ
Bir forum düşün.
İlk başta:
100 kullanıcı
bekleniyor.
Sonra:
50000 kişi geldi.
Program belleği büyütebilir.
İşte realloc tam bunun için vardır.
════════════════════════════════════════════════════════════════════
▓▓▓ NULL KONTROLÜ
malloc başarısız olabilir.
Bu yüzden:
int *ptr;
ptr = malloc(sizeof(int));
if(ptr == NULL)
{
printf("Bellek Ayrilamadi");
}
şeklinde kontrol etmek gerekir.
Profesyonel kodlarda bu zorunludur.
════════════════════════════════════════════════════════════════════
▓▓▓ DİNAMİK DİZİ
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
printf("Kac eleman: ");
scanf("%d",&n);
int *sayilar;
sayilar = malloc(n*sizeof(int));
for(int i=0;i<n;i++)
{
scanf("%d",&sayilar);
}
for(int i=0;i<n;i++)
{
printf("%d\n",sayilar);
}
free(sayilar);
return 0;
}
Artık kullanıcı kaç eleman isterse o kadar yer ayrılır.
════════════════════════════════════════════════════════════════════
▓▓▓ MALLOC İLE STRING
char *isim;
isim = malloc(50*sizeof(char));
Artık:
50 karakterlik
alan ayrılmıştır.
════════════════════════════════════════════════════════════════════
▓▓▓ POINTER + MALLOC
Aslında:
malloc
daima adres döndürür.
Bu yüzden:
Pointer olmadan kullanılamaz.
Örnek:
int *ptr;
ptr = malloc(sizeof(int));
Tamamen pointer mantığıyla çalışır.
════════════════════════════════════════════════════════════════════
▓▓▓ MİNİ PROJE #1
KULLANICI KADAR SAYI ALMA
#include <stdio.h>
#include <stdlib.h>
int main()
{
int adet;
scanf("%d",&adet);
int *sayilar;
sayilar = malloc(adet*sizeof(int));
for(int i=0;i<adet;i++)
{
scanf("%d",&sayilar);
}
for(int i=0;i<adet;i++)
{
printf("%d\n",sayilar);
}
free(sayilar);
return 0;
}
════════════════════════════════════════════════════════════════════
▓▓▓ MİNİ PROJE #2
ORTALAMA HESAPLAMA
int n;
scanf("%d",&n);
int *notlar;
notlar = malloc(n*sizeof(int));
int toplam = 0;
for(int i=0;i<n;i++)
{
scanf("%d",¬lar);
toplam += notlar;
}
printf("%d", toplam/n);
free(notlar);
════════════════════════════════════════════════════════════════════
▓▓▓ MİNİ PROJE #3
REALLOC İLE BÜYÜTME
int *ptr;
ptr = malloc(5*sizeof(int));
ptr = realloc(ptr,20*sizeof(int));
free(ptr);
Başlangıç:
5 eleman
Sonra:
20 eleman
════════════════════════════════════════════════════════════════════
⚠ YENİ BAŞLAYANLARIN HATALARI
HATA #1
malloc kullanıp free kullanmamak.
Memory Leak oluşur.
════════════════════════════════════════════════════════════════════
HATA #2
malloc sonrası NULL kontrolü yapmamak.
════════════════════════════════════════════════════════════════════
HATA #3
free edilen pointerı kullanmaya devam etmek.
Örnek:
free(ptr);
printf("%d",*ptr);
Çok tehlikelidir.
════════════════════════════════════════════════════════════════════
HATA #4
Yanlış boyut hesaplamak.
Örnek:
malloc(10);
yerine:
malloc(10*sizeof(int));
kullanılmalıdır.
════════════════════════════════════════════════════════════════════
HATA #5
Bir pointerı iki kez free etmek.
Bu ciddi program hatalarına yol açabilir.
════════════════════════════════════════════════════════════════════
▓▓▓ PROFESYONEL İPUCU
free yaptıktan sonra:
ptr = NULL;
atanması tavsiye edilir.
Örnek:
free(ptr);
ptr = NULL;
Böylece yanlışlıkla kullanma riski azalır.
════════════════════════════════════════════════════════════════════
✓ BÖLÜM ÖZETİ
Bu bölümde:
✓ Heap kavramı
✓ Dinamik bellek
✓ malloc()
✓ calloc()
✓ realloc()
✓ free()
✓ Memory Leak
✓ NULL kontrolü
✓ Dinamik diziler
✓ Dinamik stringler
✓ Pointer ilişkisi
✓ Profesyonel kullanım kuralları
konularını öğrendik.
Bir sonraki bölümde STRUCT (Yapılar) konusuna geçeceğiz. Bu bölümden sonra artık gerçek uygulamalar geliştirmeye başlayabileceğiz.