Sanal belleğin programcıyla alakalı iki kısmı var:
stack ve
heap. Stack'in genelde küçük bir sınırı vardır, 8 MB gibi (değiştirilebilir, ama genelde gerek olmaz). Heap ise bilgisayarınızdaki bellek miktarıyla sınırlı, günümüzde yüzlerce MB.
Bir function içinde array yarattığınızda stack'ten belirli bir miktar ayırılır. Eski C standartlarında bu miktarın daha programı yazarken belli olması gerekiyordu, yani
int n = 30;
int arr[n];
gibi bir kodu derleyemiyordunuz. Sanırım yeni standartta mümkün bu. Bunu sıkıntıyı aşmak için malloc kullanılır. Malloc, istediğiniz hafızayı heap'ten alır, ve size pointer verir, "al abi, sana istediğin kadar byte verdim, tepe tepe kullan" der.
Bir kaç önemli nokta:
- Array'lere pointer gibi davranabilirsiniz. Ama bir array olarak yaratılmış bir pointer'ın değerini değiştiremezsiniz, yoksa
segfault yersiniz. Yani şu yasak:
void func(int* ptr)
{
int d[30];
...
d = ptr; //olmaz
}
Bunun bir sınırı: bir kez bir array yarattığınızda boyutunu değiştiremezsiniz. Ama malloc'la aldığınız bir pointer'daki alanı
realloc ile değiştirebilirsiniz. Boyutu değişecek bir veri yapısı için bu çok faydalı ve gerekli.
- Malloc null döndürebilir. Kontrol edin.
- Malloc'la aldığınız bir bloğu, daha sonra
free fonksiyonu ile "işim bitti bunla" diyip serbest bırakın. (bkz:
memory leak) Daha sonra o pointer'ı sakın kullanmayın.
Kısacası, arrayler daha basit ve ufak diziler için rahat. Basit ve temiz oluyorlar. Ancak daha büyük hafıza blokları, ya da değişebilir boyutlar için malloc daha rahat olacaktır.
Unutmuşum: Ayrıca arrayin içindeki sayı, kaç eleman alacağını gösterir. Yani int d[20] derseniz, 20 int'lik blok ayrılır. Malloc'ta ise kaç byte istediğizi verirsiniz. Yani ptr = malloc(20) diyip oraya 20 tane int koymaya çalışırsanız, geçmiş olsun. Doğrusu malloc(20 * sizeof(int)) olacak.