08.11.2014 Views

c_kitap

c_kitap

c_kitap

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

C ve Sistem Programcıları Derneği - C Ders Notları - Necati Ergin<br />

Yukarıdaki örnek bir çok sistemde derlenip çalıştırıldığında döngü k değişkeninin 10<br />

değeri için de sürer. Oysa a[10] elemanı için bir yer ayrılmamıştır. Dizinin son elemanı<br />

a[9] elemanıdır. Derleyici a dizisi için a[0]'dan başlayarak a[9] elemanları için bellekte<br />

toplam 10 nesnelik yani 40 byte'lık bir yer ayırır. Oysa yeri ayrılmamış olan a[10]<br />

bölgesinin kim tarafından ve ne amaçla kullanıldığı hakkında herhangi bir bilgi yoktur.<br />

Bu konuda bir garanti bulunmamakla birlikte derleyicilerin çoğu, ardışık olarak<br />

tanımlanan elemanları bellekte bitişik olarak (contiguous) olarak yerleştirirler. Ama bu<br />

güvence altına alınmış bir özellik değildir. Yani bunun güvence altına alındığı düşünülerek<br />

kod yazılması problemlere yol açar. Yukarıdaki örnekte a[10] bölgesi derleyicilerin<br />

çoğunda a dizisinden hemen sonra tanımlanan ve döngü değişkeni olarak kullanılan k<br />

değişkenine ayrılır. Dolayısıyla a[10] elemanına 0 değerini vermekle aslında k<br />

değişkenine 0 değeri aktarılmış olabilir ve bu da döngünün sonsuz bir döngüye<br />

dönüşmesine yol açabilir.<br />

Köşeli ayraç işleci de bir gösterici işlecidir, bu işleci kullanarak dizi için ayrılan alanın<br />

dışına atama yapılabilir. C dili derleyicileri kaynak kodu bu amaçla denetlemezler. Ayrıca<br />

a dizisi için a[-1], a[-2].. gibi ifadeler de sözdizim açısından geçerlidir ve buraya<br />

yapılacak atamalar da gösterici hatalarına yol açar.<br />

Bazen dizi taşmalarına işlevler de gizli bir biçimde neden olabilir. Örneğin:<br />

void func()<br />

{<br />

char str[6];<br />

}<br />

printf("isim girin : ");<br />

gets(str);<br />

/***/<br />

func işlevi içinde tanımlanan str dizisi için toplam 6 karakterlik yer ayrılıyor. Standart gets<br />

işlevi klavyeden alınan karakterleri kendisine gönderilen adresten başlayarak belleğe<br />

yerleştirdikten sonra, sonlandırıcı karakteri de diziye yazar. O halde yukarıdaki örnekte<br />

programın çalışması sırasında 6 ya da daha fazla karakterin girilmesi gösterici hatasına<br />

neden olur. Sonlandırıcı karakter de ('\0') bellekte bir yer kaplayacağı için program için<br />

ayrılmış bir bellek alanı içinde bulunması gerekir. Örneğin klavyeden girilen isim<br />

necati<br />

olsun. gets işlevi bu karakterleri aşağıdaki gibi yerleştirir :<br />

Sonlandırıcı karakter, dizi için ayrılan bölgenin dışına yerleştiriliyor. Bu örnekte girilen<br />

isim daha uzun olsaydı, program için ayrılmamış bir bölgeye daha fazla karakter<br />

yazılacaktı. Bu tür hatalarla karşılaşmamak için dizi yeteri kadar uzun olmalı ya da<br />

standart bir C işlevi olan gets işlevi yerine, dizi uzunluğundan daha fazla sayıda eleman<br />

yerleştirilmesine izin vermeyecek bir işlev kullanılmalıdır. Bu amaçla fgets isimli işlev<br />

çağrılabilir. Standart fgets işlevini dosyalar konusunda göreceksiniz.<br />

Dizgelerle ilgili işlemler yapan standart C işlevlerinden strcpy, strcat, strncpy, strncat<br />

işlevlerinin yanlış kullanılması da benzer hataları oluşturabilir.<br />

282

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!