From: Serdar KÖYLÜ (serdarkoylu@fisek.com.tr)
Date: Thu 07 Aug 2003 - 21:43:43 EEST
Selamlar..
On Thu, 7 Aug 2003 21:25:58 +0300
Halil Demirezen <halild@bilmuh.ege.edu.tr> wrote:
>
> evet burada serdar arkadasimizi dogrulayacak bir kode ornegi var.
> Mesela s degiskeni bir char pointer mevcut 32 bit linuxlarda 4 byte
> bir adress. sonra gidip malloc ile 10 byte yada 10 karakterlik bir
> array olusturup pointer e bu arrayin adresini ariyoruz. Ve o pointer
> uzerinden o adrese
Biraz farkli bir is aslinda yaptiginiz.
> s = (char *)malloc(10);
s, 10 Bayt uzunlukta bir buffer (arabellek) i gosteriyor artik. Bufferin
icinde ne var belirsiz.
> s = "deneme";
> "deneme" stringini atiyoruz. Hicbir Segmentation fault alamiyorsunuz.
Hayir, s pointerinin degerine text segmentindeki "deneme" sabitinin
bulundugu adresi yazdiniz bununla. Zaten segfault vs. alacak bir sey
yok. Yazilan deger auto-alloc edilmis olan s pointerinin oldugu bellek
hanesi.
Bir onceki islemle bunun arasinda hic bir baglanti yok. s'nin icerigi
uzerine yazildigi icin kayboldu. Onceki 10 Baytlik bufferiniz artik
"garbage". Yada bir diger deyisle "Memory Leak".. Programiniz sona
erinceye kadar hafizada yer isgal edecek. Su durumda free etme sansinz
yok :))
> Ama literaller benim de tereddut ettigim gibi read only text
> segmentinde saklaniyor. Boylece herhangi bir yazma isleminde
> Segmentation Fault aliyorsunuz.
Konuyu daha iyi anlamak iicn soyle bir harita dusunelim.
0 - 100 Stack olsun.
500 - 1000 Data bolgesi (data rw-)
2000 - 4000 Kod bolgesi (text r-x)
Simdi fonksiyona girince
100 - s -> Icerigi belirsiz.
99 - return icin geri donus adresi.
s = malloc(10);
100 - s -> icerigi malloc'un dondurdugu deger olur.
. Diyelim ki malloc geriye 500 adresini dondurdu.
. bu durumda s'nin icindeki deger 500'dur. Bu, *s yazdiginizda
. kullanilacak degerdir.
*s = 1;
s = 500 olduguna gore, 500. Bellek noktasina 1 konacaktir.
Diyelimki, sabitimiz 2400. Adreste olsun.
2400 - 'A'
2401 - 'B'
2402 - 'C'
2403 - '\0'
Seklinde olur. Simdi
s = "ABC"
dedigimizde bu kez, 100. Baytta (stacktaki s degeri) bulunan
s'nin icerigi 2400 olur.
Simdi kabaca bakarsak:
0...98 - Belirsiz (STACK, burada bizi cagiran fonksiyonun degiskenleri
vs. var.)
99 - Geri donus adresi.
100 - s
101...499 - Belirsiz
500 - 509 - malloc ile ayrilmis bolge. Icerigi mechul.
510 - 2399 - Belirsiz veri ve komutlar..
2400 - 'A'
2401 - 'B'
2402 - 'C'
2403 - '\0'
2404 - .... Belirsiz..
Goruldugu uzere yeni bellek duzenimiz bu sekilde. Bu son derece
basitlestirilmis bir yapi. Dahasi sadelestirme adina bazi birazcik
hatali. Ama bellekte bu dumenin nasil dondugunu biraz ozetleyebilir.
Pointerin calisma prensibini anlamak icin bir super isaretci dusunun. Bu
isaretci nereyi gosteriyorsa CPU bellegin orasina yazacak veya okuyacak.
Eger,
ptr = 100
derseniz, bu super isaretciye ptr'nin adresi yazilir.
*ptr = 100
derseniz, super isaretci once ptr'nin oldugu adresi gosterir. ptr'nin
icindeki deger okunur ve o deger super isaretciye yazilir. Devaminda 100
sayisida bu isaretcinin gosterdigi yere yazilir. Boyle olunca
pointerlerin her zaman mutlak adresi gosterebilme yetenegi olur. Ama bir
array stack uzerinde calisir, heap (data segmenti) uzerinde bulunmaz.
Cogu derleyici icin bu gecerlidir. Ornegin "char arr[3]" belirtimi,
bizim stack'imizin soyle olmasina yol acar:
char arr[3];
char *ptr;
arr[0] = 'X';
Satirlari icin baslangicta:
100 -> ptr
99 - arr[3]
98 - arr[2]
97 - arr[1]
96 - arr[0]
95 - return icin geri donus adresi.
veya derleyicinin yogurt yemesine gore:
100 - arr[3]
99 - arr[2]
98 - arr[1]
97 - arr[0]
96 -> ptr
95 - return icin geri donus adresi.
Simdi super isaretcimiz SI olsun..
arr[n] = 'X'; komutu
SI = 97
SI = SI + n
'X' degerini yaz..
Seklinde olur. Eger
ptr = arr;
yazarsak;
SI = 96
97 degerini yaz..
Seklinde olur. Simdi
ptr[n] = 0;
SI = 96
oku
SI = okudugun deger.
SI = SI + n
0 degerini yaz..
Seklinde cevrilebilir. Dikkat ederseniz, bir array dogrudan bellegi
isaret ediyor. Bu yuzden r/w olmak durumunda. Ama bir pointer oyle olmak
zorunda degil.. Onun icinde her zaman SI dedigimiz CPU'nun nereye
yazacagini gosteren bir baska adres bulunuyor..
Simdi ne anlasiliyor ? Sanirim biraz daha aciklayici olmustur...
Saygi ve sevgiler..