ProgrammazioneSviluppatore C++

Spiega come funzionano RAII e le eccezioni in C++. Perché è importante implementare correttamente la gestione delle risorse?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

RAII (Resource Acquisition Is Initialization) è un'idioma di C++ che consente di gestire il ciclo di vita delle risorse (file, memoria, socket, ecc.) attraverso il ciclo di vita degli oggetti. Le risorse vengono allocate nel costruttore dell'oggetto e liberate nel distruttore.

Esempio di codice:

#include <fstream> viod save_data(const std::string& filename, const std::string& data) { std::ofstream file(filename); // RAII: il file si chiuderà automaticamente if (!file) throw std::runtime_error("Impossibile aprire il file"); file << data; } // il file si chiuderà qui

In caso di eccezioni, il distruttore verrà comunque chiamato, quindi le risorse non andranno perse. Senza utilizzare RAII, si possono verificare perdite di memoria e dei descrittori di file.

Domanda trabocchetto.

È possibile garantire l'assenza di perdite di memoria in C++ usando solo try/catch?

No, non è possibile. L'uso di try/catch non garantisce l'allocazione delle risorse. Solo RAII offre questa garanzia.

Esempio:

int* arr = new int[10]; try { // Operazioni su arr throw std::runtime_error("Oops"); } catch (...) { // arr non liberato, a meno che non ci sia delete[] } // arr perso!

Esempi di errori reali dovuti alla mancata conoscenza delle sottigliezze dell'argomento.


Storia

In un grande progetto di grafica, si verificavano periodicamente crash a causa dell'esaurimento dei descrittori di file. Si scoprì che i file venivano aperti in una funzione senza essere racchiusi in RAII (std::fstream), e durante il lancio di un'eccezione le risorse non venivano liberate.


Storia

In un handler di richieste di un server web si utilizzava memoria grezza senza una wrapper in smart-pointer - in caso di lancio di un'eccezione, la memoria non veniva liberata, portando a degrado delle performance e crash.


Storia

In un progetto di elaborazione delle immagini si creavano file temporanei senza un wrapper di oggetti. In caso di lancio di eccezioni, i file non venivano rimossi, portando a un riempimento di /tmp sul server dopo alcuni mesi di lavoro continuo.