Statik bellek ayırma ile dinamik bellek ayırma arasındaki farkın ne olduğunu bilmek istiyorum.
Bunu herhangi bir örnekle açıklayabilir misiniz?
Statik bellek ayırma ile dinamik bellek ayırma arasındaki farkın ne olduğunu bilmek istiyorum.
Bunu herhangi bir örnekle açıklayabilir misiniz?
Yanıtlar:
Üç tür tahsis vardır - statik, otomatik ve dinamik.
Statik Tahsis , program başladığında değişkenleriniz için hafızanın tahsis edildiği anlamına gelir. Program oluşturulduğunda boyut sabittir. Global değişkenler, dosya kapsamı değişkenleri ve static
dahili fonksiyonlar ile tanımlanmış değişkenler için geçerlidir .
Otomatik bellek tahsisi , işlevler içinde tanımlanan (statik olmayan) değişkenler için gerçekleşir ve genellikle yığın üzerinde depolanır (C standardı bir yığının kullanılmasını zorunlu kılmasa da). Bunları kullanarak fazladan bellek ayırmanız gerekmez, ancak diğer yandan bu belleğin ömrü üzerinde sınırlı kontrole sahip olursunuz. Örneğin: bir işlevdeki otomatik değişkenler yalnızca işlev bitene kadar oradadır.
void func() {
int i; /* `i` only exists during `func` */
}
Dinamik bellek tahsisi biraz farklıdır. Artık bu bellek konumlarının tam boyutunu ve kullanım ömrünü kontrol ediyorsunuz. Serbest bırakmazsanız bellek sızıntılarıyla karşılaşırsınız ve bu da uygulamanızın çökmesine neden olabilir, çünkü bir noktada sistem daha fazla bellek ayıramaz.
int* func() {
int* mem = malloc(1024);
return mem;
}
int* mem = func(); /* still accessible */
Üstteki örnekte, ayrılan bellek, işlev sonlandırılmış olsa bile hala geçerlidir ve erişilebilirdir. Hafıza ile işiniz bittiğinde, onu boşaltmanız gerekir:
free(mem);
Bu standart bir mülakat sorusudur:
Bellek calloc()
, malloc()
ve arkadaşları kullanılarak çalışma zamanında tahsis edilir . Yığın veri yapısı ref ile ilgisi olmamasına rağmen, bazen 'yığın' bellek olarak da adlandırılır .
int * a = malloc(sizeof(int));
Yığın bellek free()
çağrılana kadar kalıcıdır . Başka bir deyişle, değişkenin yaşam süresini siz kontrol edersiniz.
Bu, genel olarak 'yığın' bellek olarak bilinen şeydir ve yeni bir kapsam girdiğinizde (genellikle çağrı yığınında yeni bir işlev basıldığında) tahsis edilir. Kapsam dışına çıktığınızda, otomatik bellek adreslerinin değerleri tanımsızdır ve bunlara erişmek bir hatadır .
int a = 43;
Kapsamın işlev anlamına gelmediğini unutmayın. Kapsamlar bir işlev içinde yuvalanabilir ve değişken, yalnızca bildirildiği blok içinde kapsam dahilinde olacaktır. Ayrıca bu belleğin nereye tahsis edileceğinin belirtilmediğine dikkat edin. ( Aklı başında bir sistemde yığın veya optimizasyon için kayıtlar olacaktır)
Derleme zamanında * tahsis edilir ve statik bellekteki bir değişkenin ömrü, programın yaşam süresidir .
C'de, statik bellek static
anahtar sözcük kullanılarak tahsis edilebilir . Kapsam, yalnızca derleme birimidir.
Şeyler daha ilginç olsun zaman extern
anahtar kelime olarak kabul edilir . Bir extern
değişken tanımlandığında , derleyici onun için bellek ayırır. Bir extern
değişken bildirildiğinde , derleyici değişkenin başka bir yerde tanımlanmasını gerektirir . extern
Değişkenlerin bildirilmemesi / tanımlanamaması bağlantı sorunlarına neden olurken, static
değişkenlerin bildirilmemesi / tanımlanamaması derleme sorunlarına neden olur.
dosya kapsamında statik anahtar kelime isteğe bağlıdır (bir işlevin dışında):
int a = 32;
Ancak işlev kapsamında değil (bir işlevin içinde):
static int a = 32;
Teknik olarak extern
ve static
C'deki iki ayrı değişken sınıfıdır.
extern int a; /* Declaration */
int a; /* Definition */
Statik belleğin derleme zamanında ayrıldığını söylemek biraz kafa karıştırıcı, özellikle de derleme makinesi ile ana makinenin aynı olmayabileceğini veya hatta aynı mimaride olmayabileceğini düşünmeye başlarsak.
Düşünmek iyi olabilir statik bellek tahsisi derleyici tarafından ele alındığının ziyade derleme zamanında tahsis .
Örneğin derleyici data
, derlenmiş ikili dosyada büyük bir bölüm oluşturabilir ve program belleğe yüklendiğinde,data
programın bölümü, ayrılan belleğin konumu olarak kullanılacaktır. Bu, çok fazla statik bellek kullanılıyorsa, derlenmiş ikiliyi çok büyük yapmak gibi belirgin bir dezavantaja sahiptir. Yarım düzineden daha az kod satırından oluşturulan çok gigabaytlık bir ikili dosya yazmak mümkündür. Diğer bir seçenek, derleyicinin program çalıştırılmadan önce belleği başka bir şekilde tahsis edecek başlatma kodunu enjekte etmesidir. Bu kod, hedef platforma ve işletim sistemine göre değişecektir. Pratikte, modern derleyiciler bu seçeneklerden hangisinin kullanılacağına karar vermek için buluşsal yöntemler kullanır. Bunu, 10k, 1m, 10m, 100m, 1G veya 10G öğelerinin büyük bir statik dizisini ayıran küçük bir C programı yazarak deneyebilirsiniz. Birçok derleyici için ikili boyut, dizinin boyutuyla doğrusal olarak büyümeye devam edecek ve belirli bir noktayı geçecektir.
Son bellek sınıfı, 'kayıt' değişkenleridir. Beklendiği gibi, kayıt değişkenleri bir CPU'nun kaydına tahsis edilmelidir, ancak karar aslında derleyiciye bırakılmıştır. Bir yazmaç değişkenini bir referansa adresi-of kullanarak dönüştüremezsiniz.
register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */
Çoğu modern derleyici, hangi değişkenlerin yazmaçlara konulacağını seçmede sizden daha akıllıdır :)
int * a = malloc(sizeof(*a));
yerine, türünü tekrar etmekten kaçınmanızı öneririm a
. Bu, herhangi bir a
değişiklik olursa, işleri çok daha kolaylaştırır .
Statik Bellek Tahsisi:
Dinamik Bellek Tahsisi:
Statik bellek tahsisi: Derleyici, bildirilen bir değişken için gerekli bellek alanını ayırır.İşlecin adresini kullanarak, ayrılmış adres elde edilir ve bu adres bir işaretçi değişkenine atanabilir.Bildirilen değişkenlerin çoğu statik belleğe sahip olduğundan, bu bir işaretçi değişkenine işaretçi değeri atamanın yolu, statik bellek ayırma olarak bilinir. bellek derleme sırasında atanır.
Dinamik bellek ayırma: Belleği dinamik olarak almak için malloc () veya calloc () gibi işlevleri kullanır.Bu işlevler belleği dinamik olarak almak için kullanılıyorsa ve bu işlevler tarafından döndürülen değerler işaretçi değişkenlerine atanmışsa, bu tür atamalar dinamik bellek olarak bilinir. Tahsis. bellek, çalışma süresi boyunca atanır.
STATİK BELLEK TAHSİSİ ve DİNAMİK BELLEK TAHSİSİ Arasındaki Fark
Bellek, programın yürütülmesi başlamadan önce tahsis edilir (Derleme Sırasında).
Bellek, programın yürütülmesi sırasında tahsis edilir.
Yürütme sırasında bellek ayırma veya ayırma eylemi gerçekleştirilmez.
Bellek Bağlamaları, Yürütme sırasında oluşturulur ve yok edilir.
Değişkenler kalıcı olarak tahsis edilmiş olarak kalır.
Yalnızca program birimi etkinken atanır.
Yığınlar ve yığınlar kullanılarak uygulanır.
Veri segmentleri kullanılarak uygulandı.
Değişkenlere erişmek için işaretçi gereklidir.
Dinamik olarak ayrılmış işaretleyicilere gerek yok.
Dinamik'ten daha hızlı yürütme.
Statikten daha yavaş yürütme.
Daha fazla bellek alanı gerekli.
Daha az Bellek alanı gerekli.
Statik bellek tahsisi, derleme sırasında pf programının yürütülmesinden önce bellek olarak ayrılır. Dinamik bellek tahsisi, programın çalışma zamanında yürütülmesi sırasında ayrılmış bellektir.