ProgramlamaC++ Orta geliştirici

C++'da normal bir işaretçi ile akıllı işaretçi (örneğin, std::unique_ptr) arasındaki farkları açıklayın. Akıllı işaretçiler neden programları daha güvenilir hale getirir?

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

Cevap.

Konuya Giriş:

Normal (ham) işaretçiler, C++'da dinamik bellekle çalışmak için geleneksel mekanizmadır. Bu evrensel soyut bir mekanizma olsa da, maalesef hatalara oldukça açıktır: bellek sızıntıları, çift silme ve Dangling pointer hataları. Bu nedenle C++11 ile standart kütüphane akıllı işaretçileri içerir: otomatik olarak nesnenin yaşam süresini yöneten şablon sınıflar (std::unique_ptr, std::shared_ptr, std::weak_ptr).

Sorun:

Normal işaretçiler kullanıldığında bellek ayırma ve serbest bırakma sorumluluğu programcıya aittir. Bellek serbest bırakmadaki hatalar bellek sızıntılarına yol açar, verilerin bozulmasına ve programın çökmesine neden olur. Özellikle istisna işleme veya işaretçilerin başka işlevlere geçirilmesi durumunda karmaşık durumlar ortaya çıkar.

Çözüm:

Akıllı işaretçiler, ayrılan belleği kapsüller ve sahipleri kalmadığında otomatik olarak serbest bırakır. RAII'yi uygularlar. std::unique_ptr, özel mülkiyet sağlar; std::shared_ptr, paylaşılan; std::weak_ptr ise kontrol etmeyen işaretçidir (dönüşümlü referans döngülerini önlemek için).

Kod Örneği:

#include <memory> void foo() { std::unique_ptr<int> p = std::make_unique<int>(5); // bellek, istisna olsa bile serbest bırakılacak // ... }

Anahtar Özellikler:

  • Akıllı işaretçiler, yok edildiklerinde kaynakları otomatik olarak serbest bırakır
  • std::unique_ptr kopyalamayı yasaklar, yalnızca taşıma semantiği (move) sağlar
  • std::shared_ptr, "referans sayımı" uygular

Kandırmaca Sorular

std::unique_ptr'ı new[] ile oluşturulan bir dizi için kullanabilir miyiz?

Hayır, diziler için std::unique_ptr<T[]> kullanmalısınız: böylece delete yerine delete[] çağrılacaktır.

std::unique_ptr<int[]> arr(new int[10]);

Standart akıllı işaretçiler tüm potansiyel bellek sızıntılarını önleyebilir mi?

Hayır. Örneğin, std::shared_ptr arasındaki döngüsel referanslar bellek sızıntısına neden olur. Bu döngüleri kırmak için std::weak_ptr kullanılır.

Akıllı işaretçiler aynı nesneyi iki kez "sildebilir mi"?

Hayır, mülkiyet mantığını ihlal etmediğiniz sürece (ham işaretçiler kullanmamalısınız!). Ham bir işaretçiyi manuel olarak kopyalarsanız, yok etme iki kez gerçekleşebilir.

Yaygın Hatalar ve Anti-Desenler

  • std::unique_ptr'ı kopyalamak, derleme hatasına yol açar
  • Aynı nesne için hem akıllı hem de ham işaretçiyi aynı anda kullanmak
  • Dönüşümlü bağımlılıkları çözmek için std::weak_ptr kullanmamak

Gerçek Hayat Örneği

Olumsuz Durum

Ham işaretçiler kullanılıyor, bellek manuel olarak serbest bırakılıyor, istisna fırlatıldığında bellek serbest bırakılmıyor.

Artılar:

  • Basit sorunlarda anlaşılır

Eksiler:

  • Düzenli bellek sızıntıları
  • Potansiyel çift silme
  • Kodun bakımını zorlaştırır

Olumlu Durum

Nesneleri oluşturmak ve işlevlere aktarmak için std::unique_ptr ve std::make_unique kullanılıyor.

Artılar:

  • Bellek sızıntısı neredeyse imkansızdır
  • RAII arayüzü, nesnelerin kolay mülkiyeti ve aktarımı

Eksiler:

  • taşınma semantiği ve standart kütüphanenin çalışma mantığını anlamayı gerektirir