2011-08-14 24 views
16

Powiel możliwe:
Will exit() or an exception prevent an end-of-scope destructor from being called?Czy wywołują destruktory podczas wywoływania metody exit()?

W C++, gdy aplikacja wywołuje exit (3) są destruktory na stosie miał być prowadzony na odpoczynek stos?

+0

Czy istnieje alternatywne podejście? 'throw' specjalny typ zamiast wywoływania' exit', przechwytuje go w 'main', a następnie' return' z 'main' zamiast' exit' z 'main'? –

+1

@AaronMcDaid Nie rozumiem twojego pytania. Alternatywne podejście do czego? Co chciałbyś osiągnąć, unikając wywołania 'exit()'? W jednej z moich aplikacji wyrzucam obiekt 'customExit' i przechwytuję go w main oraz używam wartości całkowitej z obiektu' customExit' w celu dostarczenia zwracanej wartości z głównego, w ten sposób moje destruktory RAII są uruchamiane w celu czyszczenia takich rzeczy jak pliki tymczasowe. – WilliamKF

+0

Twój komentarz odpowiedział dokładnie na moje (źle napisane) pytanie. Dzięki! Zasadniczo chciałem potwierdzenia, że ​​inne osoby używają tego podejścia "rzucania", aby zapewnić, że wszystko zostanie zniszczone w normalnym wyjściu z programu. –

Odpowiedz

28

Nie, większość destruktorów nie jest uruchamiana na exit().

C++ 98 §18.3/8 omawia to.

Zasadniczo, gdy obiekty statyczne są niszczone, wykonywane są procedury obsługi atexit, otwarte strumienie C są opróżniane i zamykane, a pliki tworzone przez tmpfile są usuwane. Lokalne automatyczne obiekty nie są niszczone. To znaczy, nie rozwija się stos.

Zadzwoń pod numer abort, aby jeszcze mniej się zdarzyć: bez czyszczenia.

+0

Dla osób, które nie chcą się czyścić, _exit() może być lepszym połączeniem niż abort(), ponieważ przerwanie podniesie sygnał SIGABRT, zazwyczaj powodując zachowanie podobne do awarii. –

5

Jeśli twój system operacyjny jest rozsądny (Unix, Linux lub ostatnio Windows), wywołanie exit() mówi jądru, aby anulował przydzielanie pamięci wszystkich procesów. Stos nie musi być rozwijany; po prostu przestanie istnieć.

+13

A jakikolwiek kod RAII w destruktorach stosów NIE zostanie wywołany. Co nie ma znaczenia, jeśli dotyczy tylko pamięci prywatnej w procesie; ale ma to znaczenie, jeśli dotyczy to (a) plików, które należy usunąć lub zmienić ich nazwy, lub w inny sposób uporządkowane, oraz (b) integralności struktur danych współdzielonych między procesami we wspólnej pamięci. // Z powodów takich jak te, niektóre projekty zabroniły użycia wyjścia i/lub przedefiniowały exit(), aby rzucić wyjątek, który spowoduje rozwijanie stosu. –

Powiązane problemy