RAII (Resource Acquisition Is Initialization) ist ein C++-Idiomat, das es ermöglicht, die Lebensdauer von Ressourcen (Dateien, Speicher, Sockets usw.) über die Lebensdauer von Objekten zu verwalten. Ressourcen werden im Konstruktor des Objekts zugewiesen und im Destruktor freigegeben.
#include <fstream> void save_data(const std::string& filename, const std::string& data) { std::ofstream file(filename); // RAII: die Datei wird automatisch geschlossen if (!file) throw std::runtime_error("Kann Datei nicht öffnen"); file << data; } // die Datei wird hier geschlossen
Im Falle von Ausnahmen wird der Destruktor dennoch aufgerufen, die Ressourcen gehen nicht verloren. Wenn RAII nicht verwendet wird, kann man mit Speicher- und Dateideskriptorlecks konfrontiert werden.
Kann man in C++ garantieren, dass es keine Speicherlecks gibt, indem man nur try/catch verwendet?
Nein, das kann man nicht. Die bloße Verwendung von try/catch garantiert nicht die Freigabe von Ressourcen. Die Garantie bietet nur RAII.
int* arr = new int[10]; try { // Arbeiten mit arr throw std::runtime_error("Ups"); } catch (...) { // arr wird nicht freigegeben, wenn nicht delete[] verwendet wird } // arr ist ein Leck!
Geschichte
In einem großen Grafikprojekt kam es häufiger zu Abstürzen aufgrund erschöpfter Dateideskriptoren. Es stellte sich heraus, dass Dateien in einer Funktion ohne RAII-Wrap (std::fstream) geöffnet wurden, und bei einer Ausnahme wurden die Ressourcen nicht freigegeben.
Geschichte
Im Anfragehandler des Webservers wurde roher Speicher ohne Smart-Pointer-Wrapper verwendet – im Falle einer Ausnahme wurde der Speicher nicht freigegeben, was zu Leistungsabfällen und Abstürzen führte.
Geschichte
In einem Projekt zur Bildverarbeitung wurden temporäre Dateien ohne Objekte erstellt. Bei Ausnahmen wurden die Dateien nicht gelöscht, was nach mehreren Monaten kontinuierlicher Arbeit zu einer Überfüllung von /tmp auf dem Server führte.