programowanieProgramista C++

Opowiedz, jak działają RAII i wyjątki w C++? Dlaczego ważne jest poprawne zarządzanie zasobami?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

RAII (Resource Acquisition Is Initialization) to idiom C++, który pozwala zarządzać czasem życia zasobów (plików, pamięci, gniazd itp.) poprzez czas życia obiektów. Zasoby są przydzielane w konstruktorze obiektu i zwalniane w destruktorze.

Przykład kodu:

#include <fstream> void save_data(const std::string& filename, const std::string& data) { std::ofstream file(filename); // RAII: plik zamknie się automatycznie if (!file) throw std::runtime_error("Nie można otworzyć pliku"); file << data; } // plik zamknie się tutaj

W przypadku wystąpienia wyjątków destruktor i tak zostanie wywołany, zasoby nie uciekną. Jeśli nie używasz RAII, możesz napotkać na wycieki pamięci i deskryptorów plików.

Pytanie z haczykiem.

Czy można zagwarantować brak wycieków pamięci w C++, używając tylko try/catch?

Nie, nie można. Samo użycie try/catch nie gwarantuje zwolnienia zasobów. Gwarancję daje tylko RAII.

Przykład:

int* arr = new int[10]; try { // Praca z arr throw std::runtime_error("Ups"); } catch (...) { // arr nie zwolniono, jeśli nie było delete[] } // arr uciekł!

Przykłady rzeczywistych błędów z powodu niewiedzy na temat szczegółów tematu.


Historia

W dużym projekcie graficznym regularnie występowały awarie z powodu wyczerpania deskryptorów plików. Okazało się, że pliki były otwierane w funkcji bez owijania w RAII (std::fstream), a przy rzucaniu wyjątków zasoby nie były zwalniane.


Historia

W obsłudze zapytań serwera WWW używano surowej pamięci bez owijania w wskaźnik typu smart – w przypadku rzucenia wyjątku pamięć nie była zwalniana, co prowadziło do degradacji wydajności i awarii.


Historia

W projekcie przetwarzania obrazów tworzone były pliki tymczasowe bez owijania obiektami. Przy rzucaniu wyjątków pliki nie były usuwane, co prowadziło do przepełnienia /tmp na serwerze po kilku miesiącach ciągłej pracy.