C++ dizileri anlatırken -> C++ Diziler konusunda, dizilerin boyutlarının önceden belirtilmesi gerektiğinden bahsetmiştik, bunun nedeni olarak da programın çalışmadan evvel o dizi için ne kadar yer ayırmalı bilmesi gerektiğini söylemiştik, hatta iki boyutlu dizileri yazdığım yazıda dizi boyutlarını sabitler içerisine atarak tanımlama yapmıştık. Hadi deneysel düz bir kafada ilerleyelim ve bunu değişkenlerle yapmayı deneyelim :
int n = 3; int arr[n];
Bunu yaptığımız anda Visual Studio daha kodu bile derlemeden tanımlamayı yaptığımız ikinci satırda n 'in altını çizdi ve Error List 'e şu hatayı yazdırdı :
Error (active) E0028 expression must have a constant value
Şair burada; ifade sabit bir değer olmalı demek istiyor. Birisinin çıkıp sevgili şairimize her zaman bir dizinin eleman sayısının sabit olamayacağını bazen parametrik olarak kullanılabilmesi için bize imkan tanıması gerektiğini anlatması gerekecek. Ya da başka bir şekilde yapılmış bir hesaplama sonucu ortaya çıkıyor/belirlenebiliyor da olabilir, örnekler çoğaltılabilir, özetle sabit değil değişken bir eleman sayısı durumu elde etmek istiyoruz.
Bu noktada ihtiyaç duyduğumuz şeyin adı Dynamic Arrays. Programlamada dinamik ne demek? Dinamik kelimesi literatürde, runtime yani programın çalıştığı süreçte oluşturulan anlamına gelir. Bu ne demek, biz bu kodu yazdığımızda bu değerin ne olduğunu bilmiyoruz, bilemiyoruz, yahut kullanıcının belirlemesini istiyoruz vesaire gibi sebeplerle, ben sana bu bilgiyi ancak sen çalışırken verebileceğim manasında, değişik alanlarda kullanabileceğimiz güzide bir kelime olur kendisi.
Aslında konu bu noktada dizilerden çıkar, göstericiler olarak türkçeye çevirdiğimiz pointers konusundayızdır artık, işin aslı evvelce de söylediğimiz gibi; dizi dediğimiz şey arkaplanda bir göstericidir. Burada da göstericilerin bir kullanımını görmüş olacağız, uzatmıyalım nasıl yapıyoruz :
int n = 3; int *arr = new int[n];
dediğimizde şair bizi üzecek herhangi bir hata vermiyor. Kullandığımız asteriks * işareti bu arkadaşın bir pointer olduğunu bildirmek için kullanılıyor. Artık üst satırlarda diziyi başlattığımız ana kadar ister bir hesaplamayla ya da kullanıcı girişiyle almış olalım, n değişkenini dizinin eleman sayısı olarak kullanabildik. Kullandığımız new keyword başka bir yazının temel konusu olabilecek nitelikte bir arkadaş ama kısaca int türünde yeni bir nesne oluştur diyebiliriz.
Peki dizi elemanlarına nasıl değer atayacağız?
arr[0] = 3;
şeklinde atayabiliyoruz, dizi elamanlarına ulaşırken de değişen bir durum yok, değişkenadı[index].
Unutmamız gereken bir diğer nokta ise, bu diziyi new keyword ile oluşturduğumuz için, işimiz bittiğinde delete keyword ile silmemiz gerektiği, her new keyword ile oluşturulan nesne hafızada boyutu kadar yer kaplar, delete ile silinmezse de kaplamaya devam eder, hafıza organizasyonu konusunda önemli bir noktadır:
delete[] arr;
Dinamik arrayların kullanılmasındaki bir diğer handikap ise yine malesef new delete meselesinden kaynaklı, nesne new edilip delete edilemeden kod herhangi bir şekilde bir exception a düşer de nesneyi delete edemezse, ve bu kod parçacığı bir döngünün içindeyse yahut çok fazla yerde kullanılıp çağırılıyorsa, hafıza fonksiyon her çağırıldığında aynı miktarda artmaya devam eder, bu ram in tamamen dolmasına ve programın çakılıp kalmasına kadar gidebilir. Yaw bu program burda neden çakılıyor hata da yook diye kafayı yedirten bir meseleye sebebiyet verebilir, dikkat! :)
örnek olarak şu kod için :
void func_to_show_mem_leak() { int* ptr = new int(5); return; } int main() { while (true) func_to_show_mem_leak(); }
9 saniye gibi bir sürede 4gb RAM kullanımına sebebiyet verdiğini görebiliyoruz :
Haydi bir de ekrana yazdıralım dersek, şu yolu izleyebiliriz :
for (int i = 0; i < n; ++i) { cout << arr[i] << ' '; }
Önceki Konu : C++ ile çok boyutlu diziler ve kullanımı
Sonraki Konu : C++ std::vector ile dinamik diziler
Hiç yorum yok:
Yorum Gönder