11 Kasım 2008 Salı

C++ Dizi İşlemlerinde Dikkat Edilmesi Gerekenler

Bu yazıda C++ kullanıcıları için çok önemli bir şeye değineceğim. Bunu da edindiğim acı tecrübeden yola çıkarak yazıyorum. C++ bildiğimi zannederdim, okulda hocamızın verdiği ödevde uzun zaman sonra C++ kullanmam gerekiyordu. 2 gün boyunca boş zamanlarımda sadece char dizisini almaya ve bunu print etme işlemine çalıştım inanın. Bu ödevin önemli bir kısmını tamamlamış bulunuyorum :). Bu ödevi yaparken karşılaştığım ve yapılması yüksek ihtimal mantık hatalarından bahsedeceğim. Bu konulara hakim olup dikat etmeniz önemli. Bu sorunlarla ben karşılaştım başkaları karşılaşmasın. Bi göz atmanızı tavsiye ederim.
Aşağıda anlatacağım işlemlerde char* array = new char[20]; dizisini kullanacağım.

1 - Öncelikle 20 karakter tutabilecek bir diziye bellekten yer ayırdık. Şimdi buna array[0] = 'a'; değerini atayalım ve print edelim. a___-----_İİİ gibi anlaşılmaz şeyler print edecektir. Bunun için yer ayırdığımız dizinin her bir elemanını dolaşarak temizlemeliyiz.
for(int i=0 ; i<20;>i++)
{
array[i] ='\0'; // \0 null demektir.
}


2 - Şimdi bu diziye ilk değer olarak array[0] = 'a'; atadık. Biliyorsunuz ki dizinin son elemanından sonra null değeri vardır bu da dizinin bittiği anlamına gelir. O yüzden bu diziyi başka işlemlerde kullanacaksanız, sonunu null yapmazsanız hata alma olasılığınız çok yüksektir. Bunu önlemek için de verdiğimiz en son değerden sonraki değeri null yapmalıyız. Yani array[1] = '\0'; değerini mutlaka vermeliyiz.

3 - array[0] = '2' ile array[0] = 2 aynı şey değildir bunu çoğu kimse bilir yine de buraya ekleyip hatırlatmanın iyi olacağını düşündüm.

4 - Uzunluk ile ilgili problem. Programda int uzunluk = strlen(array); diye uzunluğu bulduk diyelim ve uzunluk = 5 olsun, dizinin de dolu olduğunu düşünelim. Dizide array[uzunluk] = 'a'; demek veya for döngüsü içinde
for(int i=0 ; i <= uzunluk; i++) {
array[i] ='a';
}
bu şekilde kullanmak programın runtime ında hataya sebep olacaktır. Çünkü diziler indis olarak 0 dan uzunluk - 1' e kadardır.

5 - Dizinin ilk 0 elemanının dolu olduğun düşünelim. 'ahmetuzun'. array[1] = '\0' yani dizinin ikinci elemanının değerini null yapıyoruz. Diziyi print ettiğiniz zaman ekrana gelen a olacaktır. strlen(array) in sonucu da 1 olacaktır. Yani dizi dolu olsa bile, null değerini koyduğumuz yerden sonraki veriler kaybolur.

6 - Şimdi yeni bir dizi tanımlıyoruz. char* temp = new char[20]; bu dizi genelde geçici bir dizi olarak tanımlanır ve işi bittiğinde silinir. temp dizisini tanımladık ve temp dizisine temp = array diyerek yukarıda tanımlamış olduğumuz diziyi atadık. Daha sonra temp dizisini kullandık ve delete[] temp; diyerek bu diziyi bellekte boşuna yer kaplamasın diye sildik.
Eğer bu şekilde yaparsanız array dizimizde silinir. Çünkü bu diziler referansa göre çağırılırlar. Yani çağırılan dizinin bellek adresine bakılır. temp = array demekle bu iki dizinin bellek adreslerini bir yapmış oluyoruz. Bu yüzden temp silinirse array de gider. Zaten görüldüğü üzere burada temp dizisiyle array dizisi bellekte aynı yeri kapladığı için silmeye gerek de yok.

Daha bu tarz yapılabilecek hatalar varsa eklerim. Sizlerin bildiğiniz bu tarz hatalar varsa onları da eklerim :D

Hiç yorum yok: