From: Serdar KÖYLÜ (serdarkoylu@fisek.com.tr)
Date: Thu 07 Aug 2003 - 18:21:50 EEST
Selamlar..
Sorunuzun cevabi biraz derleyicinize filan bagli.
gcc, sabitleri text segmentlerinde tutar. Bu segmentler varsayilan
olarak r-x seklinde kullanilir. Demekki sizin "deneme" leriniz sadece
okunabilir bir bellek bolgesinde. Bu durumda s1 pointerinin gosterdigi
bellek bolgesine bir sey yazamazsiniz. Demekki kodunuz asla s2[0] yazan
yere ulasamamali. s1[0] = 'X'; dogrudan SIGSEGV ile sonuclanmali.
Denemedim ama oyle olmasi gerekiyor. Eger kodunuz bir sekilde bu s1[0]
satirini asabiliyorsa ilginc bir durum olmali.
s2[] ile *s1 ayni sey degildir. Arraylar dogrudan (direct) erisilir.
Pointerler ise dolayli (indirect) erisilir. Simdi bu ne demektir ? Siz
eger s2[n] e (array) erismek isterseniz, CPU s2 adresini alir, o
adresten n ilerleyip oradaki degere ulasir. Ama s1[n] (pointer) icin
once s1'i alir, sonra s1'icindeki adresi alir ve bu adresten itibaren n
sonraki degere ulasir.
Adresleme indirect yapildigi icin, derleyici s1 = "fesmekan" durumunda,
s1'i dogrudan text segmentindeki sabit degerin adresine esitler.
s2[]="filan" dediginiz zaman once "filan" ve \0 tutacak kadar bellekte
(genelde stack uzerinde) yer acilir ve oraya text segmentindeki "filan"
baytlari transfer edilip burasi s2 olarak kullanilmaya baslanir.
Kisaca, arrayler hafizanin kendisi oldugu icin, arraya atadiginiz deger
hafizada bir yer olacak, bunun icinde data segmenti kullanilacaktir.
sabit degerler text segmentinde dataya transfer edilecektir.
Pointerlerde ise, pointer bilginin adresini gosterdigi icin dogrudan
text segmentindeki sabitin adresine esitlenecektir.
Bu durumda s2[0] = 'x' gecerlidir, cunku s2 bir array olup, data
segmentinde bulunur. Ama s1[0] = 5 gecersizdir, cunku s1, text
segmentindeki "deneme" sabitinin adresidir. text segmenetleri r-x'tir.
Yani sadece okunabilir ve komut calisabilir. Data segmentleri ise rw-
seklindedir. Buda, okunur/yazilir ama kod calistirilamaz anlamina gelir.
Sonucta sizin, printf'e ulsamadan, text segmentine yazma girisiminiz
olan s1[0] = 'X' satirinda SIGSEGV ile muhatap olmaniz icap etmektedir.
Eger oyle degilse, gercekten incelemeye deger bir husus var demektir.
GCC, GLIBC, Kernel tayfasini vaziyetten haberdar kilmak gerekebilir..
Umarim yeterince anlasilir olarak anlatabilmisimdir. Eger bir yerlerde
pointer ile ayni seydir gibi bir sey okumussaniz bunun cogu zaman yeni
baslayanlari programcilara fazla yuklenmemek icin soylenmis bir sey
oldugunu kabul edin. Pointer farkli bir seydir, array ile aslen uzaktan
yakindan alakali degildir. Arraylari pointer gibi kullanamzsiniz. Ama
pointerleri bir arrayin adresine esitleyip array gibi kullanabilirsiniz.
elbette boyle bazi puf noktalari damdan duser gibi basiniza dusebilir.
Bu durumda da boyle sorar, sorusturur, konuya vakif olabileceginiz
bilgileri edinirsiniz. Iste C kullanmak, size boyle pek cok puf
noktasini ogretir, diger dillerden farkli olarak..
Saygi ve sevgiler..
On Thu, 7 Aug 2003 17:02:16 +0300
"turkuax" <kirikhanli@hotmail.com> wrote:
> sorunum su;
> int main()
> {
> char* s1 ="deneme";
> char s2[] = "deneme";
>
> s1[0] = 'X';
> s2[0] = 'X';
>
> printf("%s\n",s1); /* Bu satirda segmentation fault yiyorum */
> printf("%s\n",s2); /* Burada sorun cikmiyor */
> }
>
> Bu iki tanim arasindaki farki bilen birileri bana yardim ederse
> sevinirim.
>
>