ProgramlamaSistem Geliştirici

Rust'ta stack ile heap arasındaki fark nedir? Rust, bellekle çalışma güvenliğini çöp toplayıcısı olmadan nasıl sağlar?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Sorunun Tarihi

C/C++ ve diğer düşük seviyeli dillerde, geliştirici verilerin bellekte yerleşiminden açıkça sorumludur: yığın (otomatik değişkenler) veya küme (malloc/new ile tahsis). Bu dillerde bellek sızıntısı, çift serbest bırakma veya başlatılmamış ya da zaten silinmiş bellek kullanımı gibi hatalar sıklıkla meydana gelir. Rust, çöp toplayıcısı kullanmadan, bellek üzerindeki sıkı kontrol görevini üstlenir.

Sorun

Yığın ile otomatik bellek yönetimi kullanışlıdır, ancak (yığın derinliği) boyutlarla sınırlıdır. Kümede tahsis gerektirir ve kaynakların açıkça yönetilmesi tehlikelidir: belleği serbest bırakmayı unutmak ya da işaretçilerin yaşam alanlarını ihlal etmek mümkündür. Çöp toplayıcısı her zaman bir çözüm değildir (kaynak maliyetleri, öngörülemeyen kesintiler). Bellek yönetim hataları kazalara ve güvenlik açıklarına yol açar.

Çözüm

Rust'ta yığın ve küme otomatik yönetimle farklılaşır: tüm değerler varsayılan olarak yığında yerleştirilir, dinamik olarak boyutlandırılmış veya uzun ömürlü nesneler için küme kullanılır (örneğin, Box<T>, Vec<T>). Mülk ve ödünç alma sistemi, mülkü devrettikten veya yaşam alanı sona erdikten sonra kaynakların otomatik olarak serbest bırakılmasını garanti eder. Tüm bunlar, derleme aşamasında güvenli garanti sağlar ve çöp toplayıcısının gereksiz kesintilerini ortadan kaldırır.

Kodu örneği:

fn main() { let a = 42; // yığın tahsisi let b = Box::new(42); // küme tahsisi let mut v = Vec::new(); v.push(1); v.push(2); // dizinin verileri kümede }

Ana özellikler:

  • Basit türlerin (Copy) varsayılan olarak yerleşimi yığında yapılır.
  • Dinamik koleksiyonlar ve Box<T> küme kullanır, ancak RAII ile serbest bırakılır.
  • Tüm bellek, manuel müdahale veya GC olmadan garanti edilir.

Kandırmaca Sorular.

Yığında belleği manuel olarak serbest bırakabilir miyim (drop)?

Hayır. Yığın tahsisli değişkenlerin serbest bırakılması, görünüm alanından çıkıldığında otomatik olarak gerçekleşir; manuel olarak drop yapmak gereksizdir ve yığın işaretçileri için bile geçersizdir.

Taşınabilir (move) bir değişkeni kümeye taşır mı?

Hayır. Bir değişkenin sahipleri arasındaki taşıma, onu her zaman kümeye taşımayı gerektirmez, sadece mülkiyet değişir.

Box<T> kullanımı T'nin her zaman kümede olduğu anlamına gelir mi?

Evet, Box<T> gerçekten T'yi kümede tahsis eder; ancak mülkiyet ve yaşam alanı yine de sıkı bir şekilde kontrol edilir.

Tipik Hatalar ve Anti-Patinajlar

  • Referansların yaşam alanlarıyla ilgili karışıklık, bir işlevden yerel yığın nesnesine referans döndürmeye çalışma.
  • Gereksiz yere küçük nesneler için kümeyi kullanmak (malloc yükü).
  • Koleksiyonlar ve Box<T> için mülkiyet ve hareket anlamalarını göz ardı etme.

Hayat Örneği

Olumsuz Durum

Projede, mem::forget veya drop ile manuel temizlik uygulayan küresel vector'lar (Vec<T>) kullanılır, bu da zaman zaman silinmiş bellekte askıda işaretçilerin kalmasına neden olur.

Artılar:

  • Çok esneklik ve manuel kaynak yönetimi.

Eksiler:

  • Hata ve sızıntı riski yüksektir, güvenliği kötüleştirir.

Olumlu Durum

Nesneler açıkça Box aracılığıyla yerleştirilir, verilerin aktarımı mülkiyet kuralına göre gerçekleşir, koleksiyonlar için akıllı işaretçiler kullanılır ve yığın değişkenlere referans verilmez.

Artılar:

  • Sızıntı veya çift serbest bırakma riski yoktur.
  • Yaşam alanına göre otomatik serbest bırakma.

Eksiler:

  • Programın yapısı karmaşık olduğunda yaşam süreleri üzerinde düşünmek gerekebilir.