Merhaba, tekrar hoş geldiniz. Bu derste, dinamik bellek tahsisi hakkında konuşmak istiyorum.
Bu doğrudan işaretçilerle ilgilidir, bunu yalnızca işaretçiler üzerinde kullanabilirsiniz.
Öyleyse başlayalım.
Dolayısıyla, c'de bir değişken tanımladığınızda,
derleyici veri türüne bağlı olarak sizin için doğru miktarda depolama alanını otomatik olarak ayırır.
Bunu hep gördük. Tamsayılar, kayan noktalar, çiftler oluşturduğumuzda, herhangi bir bellek ayırmamız gerekmez.
Derleyici bunu sizin için yapar. Aslında bir miktar bellek ayırır.
Aynı şey işaretçiler için de geçerli bu arada. Bir işaretçi oluşturduğunuzda, bellek sizin
için tahsis edilir, böylece bir işaretçi türü, bir adres depolar.
Şimdi bu, belleğin o adres için tahsis edildiği anlamına gelmez.
Bu noktaya kadar, bir -- işaretçiye veri atadığımızda,
her zaman mevcut bir değişkeni atadık.
Dolayısıyla, bir işaretçiye veri atamak
istediğimizde, değişken için zaten bellek ayrılmış olan bir değişken
üzerinde işlecin ampersand adresini kullandık.
Peki ya bir işaretçi oluşturmak istiyorsanız ve ona operatörün adresini atamak istemiyorsanız,
belleği dinamik olarak tahsis etmek istiyorsanız. Bütün bu konuşmanın amacı da bu.
Bu nedenle, bir program çalışırken dinamik olarak depolama alanı tahsis edebilmek
sıklıkla istenen bir durumdur. İhtiyaç duyduğunuzda bellek ayırın.
Bir dosyadan bellekteki bir diziye bir dizi veri okumak için tasarlanmış
bir programınız varsa, üç seçeneğiniz vardır.
Diziyi, derleme zamanında mümkün olan en fazla sayıda eleman içerecek şekilde tanımlayabilirsiniz,
bu sabit bir boyuttur.
Eğer 50 elemanlı bir dizi tanımlarsanız, bu dizi
sadece 50 eleman içerecektir. Derleyici bunun 50 olduğunu belirlerse, çalıştırıldığında
bu kadar bellek ayıracaktır.
Dizi çalışma zamanının boyutunu boyutlandırmak için değişken uzunluklu bir dizi kullanabilirsiniz.
Bu değişken uzunluklu diziler hakkında biraz konuştuk,
C11'e kadar desteklenmiyorlar. Aslında C11'i çıkarıyorlar, C99'u ekliyorlar.
Burası değişkenleri koyabileceğiniz yerdir.
Ancak bunlar hala sabit boyutludur çünkü değişken
bağlantılı diziler anlamına gelen tek şey, boyutlar için değişkenler geçebilmenizdir.
Ama hala statikler.
Ya da en iyi seçenek, ihtiyaç duyduğunuzda diziyi dinamik olarak tahsis edebilirsiniz.
Ve bunu yapmak için çağırabileceğiniz farklı c fonksiyonları vardır.
Bu yüzden dinamik olarak bellek tahsis edebilmek çok faydalı olacaktır.
Şimdiye kadar uyguladığımız ilk yaklaşımda, ister dizi ister
veri türü olsun, sabit bir boyut söz konusudur.
Dizinizi, bir diziye doğru olacak maksimum eleman sayısını içerecek
şekilde tanımlamanız gerekir.
Yani şöyle bir şey yaparsınız: int dataArray [1000].
Bunun anlamı, veri dosyasının binden fazla öğe içeremeyeceğidir.
Eğer öyleyse, programınız bozulacaktır.
Bu nedenle, okuduğunuz dosyanın çok fazla veri içermemesini ummanız gerekir.
Programınız büyük dosya kümeleri veya büyük dosyalarla çalışmayacaktır.
Ve eğer büyük dosyalarla çalışmak istiyorsanız, geri dönmeniz ve diziyi büyütmeniz gerekir.
Boyutu değiştirmeniz gerekir, ancak
daha sonra tüm bu şeyleri yeniden derlemeniz gerekir, bu derleme zamanıdır.
Hangi değeri seçerseniz seçin, sabit bir boyut olduğu için gelecekte
aynı sorunla tekrar karşılaşma şansınız her zaman vardır.
Bu boyut, kodu derlediğinizde belirlenir,
programı çalıştırdığınızda ayarlanmaz.
Dinamik olarak değişmez.
Dinamik bellek ayırma işlevlerini kullanarak, ihtiyaç duyduğunuzda depolama alanı elde edebilirsiniz.
Bu yaklaşım, program yürütülürken bellek ayırmanıza olanak tanır.
Bunun avantajlarını bir düşünün. Her şeyden önce, kullanmayacağınız
bir ton bellek oluşturmazsınız, yalnızca ihtiyacınız
olduğu kadarını oluşturursunuz.
Ve daha fazlasına ihtiyacınız olursa, daha fazlasını tahsis edebilirsiniz.
Geri dönüp yeniden derlemeniz ve boyutu değiştirmeniz gerekmez.
Bu yüzden dinamik bellek tahsisi yapılması gereken yoldur.
İşaretçi kavramına dayanır ve kodunuzda
işaretçi kullanmak için güçlü bir teşvik sağlar.
İşaretçilerin avantajlarından bahsettik ve kendi kendinize
şöyle düşünmüş olabilirsiniz, tamam, bunlar harika bir kavram ama neden bunları kullanmamız
gerekiyor, bu en büyük nedenlerden biri,
böylece belleği dinamik olarak tahsis edebilirsiniz.
Ve yine, bu nedir -- C tamamen verimli bir dil olmakla ve bir ton bellek
kullanmamakla ilgilidir.
Bu yüzden c gömülü sistemlerde, gerçek zamanlı programlamada çalışır
ve bunun nedenlerinden biri de ihtiyaca göre ne kadar bellek kullanacağınızı
sınırlayabilmenizdir.
Dolayısıyla dinamik bellek tahsisi, verilerin depolanması için belleğin program yürütülürken dinamik olarak
tahsis edilmesini sağlar.
Dinamik olarak bellek ayırmak sadece işaretçileriniz
olduğu için mümkündür.
Bir adresiniz olduğundan ve işaretçinin ne kadarını
gösterdiğini değiştirebildiğinizden, belleği yeniden ayarlayabilirsiniz.
Üretim programlarının çoğu dinamik bellek tahsisi kullanacaktır.
Eğer c'de kod yazıyorsanız, bunu kullanacaksınız.
Yeni başlayan biri olsanız bile, dinamik bellek
tahsisini kullanacaksınız. En kullanışlı programlar bu konsepti kullanacaktır.
Verileri dinamik olarak ayırmak, çalışma zamanında görev için ihtiyaç duyduğunuz
veri miktarını tutacak kadar büyük işaretçiler oluşturmanıza olanak tanır, böylece
belleği boşa harcamamış olursunuz. Hayati.
Ayrıca yığın ve yığın hakkında da konuşmalıyız.
Bir programda belleği depolamanın iki yolu vardır, iki farklı veri
yapısı, verileri yığında depolayabilirsiniz ya da verileri heap üzerinde depolayabilirsiniz.
Dinamik bellek tahsisi heap üzerindeki her şeyi ayırır.
Bunların nasıl organize edildiğinin detaylarına girmeyeceğiz ama temel olarak.
Verileri yığın üzerinde depoladığınızda daha fazla değişikliğe
izin verirsiniz.
Veri nesnelerinin boyutunu keyfi olarak değiştirebilirsiniz ve bir
yığın içinde bellek ayırdığınızda çok daha uzun süre kalır,
programınızın tamamında kalır.
Bir yığın kullandığınızda, daha sınırlayıcı olur.
Yığın, işlev argümanlarından yerel değişkenlere kadar her şey için kullanılır.
Her şey burada saklanıyor.
İşte bu yüzden çağrı yığınından bahsettik.
Yöntemlere ve işlevlere
baktı. Arada sırada metotları kullanıyorum, ancak metotlar gerçekten nesne yönelimli
bir terim, yani fonksiyonlar.
Fonksiyonlarla ilgili her şey yığın üzerinde oluşturulur.
Bunun anlamı, bir işlevi çalıştırdığınızda,
işlevin yığına yerleştirilmesidir. Yerel değişkenler yığına yerleştirilir.
İşlevden çıktığınızda her şey silinir.
Dolayısıyla, yığın üzerinde bulunan bellek çok uzun süre kalmaz.
Dinamik olarak bellek ayırdığınızda bunun heap üzerinde olmasının nedenlerinden
biri de budur, çünkü ne zaman
kullanacağınızı ve ne zaman kullanmayacağınızı kontrol edersiniz, ayırırsınız ve silersiniz.
Yığındaki şeyleri kontrol edemezsiniz. Otomatik olarak silinir, otomatik
olarak tahsis edilir.
Yani yerel değişkenler, main gibi fonksiyonların içindeki değişkenler,
bunlar yığın üzerinde oluşturulur.
Yığın üzerindeki bellek farklıdır, programcı olarak sizin tarafınızdan kontrol edilir.
Yığın üzerinde bellek ayırdığınızda, ayırdığınız belleğin artık gerekli olmadığını takip
etmek size bağlıdır, bu nedenle belleği silmeniz gerekir.
Artık sizin tarafınızdan kullanılmadığında
alanı boşaltmanız gerekir. Ve bu önemlidir çünkü
hafıza çok ama çok kıt bir kaynaktır.
Bugün bir bilgisayarı çalıştırabileceğiniz çok fazla belleğimiz
var, 12 gig, 16 gig her neyse. Ancak cihazlarda çalışan
gömülü programlar için o kadar fazla belleğe sahip
olmanız gerekmez. Bu nedenle ne kadar bellek kullanılacağını kontrol
etmek ve ayrıca işiniz bittiğinde diğer uygulamaların kullanabilmesi için belleği
serbest bırakmak istersiniz.
Yine, düşük seviyeli gömülü tip sistemlerinde daha önemlidir.
Ancak bu, birçok dilin sahip olmadığı bir özgürlüktür. Yönetici belleğinizi programcı
tarafından kontrol etme yeteneği, programı çok daha verimli
ve çok daha hızlı hale getirebilir.
Bir sonraki derste bunu nasıl yapabileceğinizi, hangi fonksiyonları
çağırabileceğinizi konuşacağız. Açıkçası, belleği serbest bırakmak için bellek ayırmak
üzere çağırabileceğiniz farklı işlevler vardır. Teşekkür ederim.