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:
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.
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:
Eksiler:
Nesneleri oluşturmak ve işlevlere aktarmak için std::unique_ptr ve std::make_unique kullanılıyor.
Artılar:
Eksiler: