RAII (Resource Acquisition Is Initialization), C++'da kaynakların (dosyalar, bellek, soketler vb.) yaşam süresini nesnelerin yaşam süresi üzerinden yönetmeye izin veren bir idiomdur. Kaynaklar nesne oluşturucusunda tahsis edilir ve yıkıcıda serbest bırakılır.
#include <fstream> void save_data(const std::string& filename, const std::string& data) { std::ofstream file(filename); // RAII: dosya otomatik olarak kapanacaktır if (!file) throw std::runtime_error("Dosya açılamıyor"); file << data; } // dosya burada kapanacaktır
İstisnalar meydana geldiğinde, yıkıcı yine de çağrılacaktır, kaynaklar bellek sızıntısına neden olmayacaktır. RAII kullanılmadığında bellek ve dosya tanımlayıcıları sızıntılarıyla karşılaşabilirsiniz.
C++'da sadece try/catch kullanarak bellek sızıntılarının olmamasını garanti edebilir miyiz?
Hayır, edemezsiniz. Sadece try/catch kullanmak kaynakların serbest bırakılmasını garanti etmez. Garanti sadece RAII ile sağlanır.
int* arr = new int[10]; try { // arr ile çalışma throw std::runtime_error("Oops"); } catch (...) { // arr serbest bırakılmadı, eğer delete[] yoksa } // arr sızdı!
Hikaye
Büyük bir grafik projesinde dosya tanımlayıcılarının tükenmesi nedeniyle zamanla çökmeler meydana geldi. Anlaşıldı ki, dosyalar RAII (std::fstream) ile sarmalanmadan açılmış ve istisna fırlatıldığında kaynaklar serbest bırakılmamış.
Hikaye
Bir web sunucusunun istek işleyicisinde ham bellek kullanılmış, akıllı işaretçi ile sarmalanmamış - bir istisna fırlatıldığında bellek serbest bırakılmamış, bu da performansın düşmesine ve çökmelere neden olmuştur.
Hikaye
Görüntü işleme projesinde geçici dosyalar nesnelerle sarmalanmadan oluşturulmuş. İstisnalar fırlatıldığında dosyalar silinmemiş, bu da sunucuda birkaç ay süren kesintisiz çalışmadan sonra /tmp'nin dolmasına neden olmuştur.