En C y C ++, ¿cuál es la diferencia entre exit()y abort()? Estoy tratando de finalizar mi programa después de un error (no es una excepción).
En C y C ++, ¿cuál es la diferencia entre exit()y abort()? Estoy tratando de finalizar mi programa después de un error (no es una excepción).
Respuestas:
abort()sale de su programa sin llamar atexit()primero a las funciones registradas , y sin llamar primero a los destructores de objetos. exit()hace ambas cosas antes de salir de su programa. Sin embargo, no llama a destructores para objetos automáticos. Entonces
A a;
void test() {
static A b;
A c;
exit(0);
}
Destruirá ay bcorrectamente, pero no llamará destructores de c. abort()no llamaría destructores de ninguno de los objetos. Como esto es desafortunado, el estándar C ++ describe un mecanismo alternativo que garantiza la terminación adecuada:
Los objetos con duración de almacenamiento automático se destruyen en un programa cuya función
main()no contiene objetos automáticos y ejecuta la llamada aexit(). El control se puede transferir directamente a talmain()mediante una excepción atrapadamain().
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
int main() {
try {
// put all code in here
} catch(exit_exception& e) {
exit(e.c);
}
}
En lugar de llamar exit(), organice ese código en su throw exit_exception(exit_code);lugar.
abort envía una señal SIGABRT, la salida solo cierra la aplicación y realiza una limpieza normal.
Puede manejar una señal de aborto como lo desee, pero el comportamiento predeterminado es cerrar la aplicación también con un código de error.
abort no realizará la destrucción de objetos de sus miembros estáticos y globales, pero la salida sí.
Por supuesto, sin embargo, cuando la aplicación esté completamente cerrada, el sistema operativo liberará cualquier memoria no liberada y otros recursos.
En tanto aborto y la salida de la terminación del programa (asumiendo que no anular el comportamiento por defecto), el código de retorno será devuelto al proceso padre que se inició su aplicación.
Vea el siguiente ejemplo:
SomeClassType someobject;
void myProgramIsTerminating1(void)
{
cout<<"exit function 1"<<endl;
}
void myProgramIsTerminating2(void)
{
cout<<"exit function 2"<<endl;
}
int main(int argc, char**argv)
{
atexit (myProgramIsTerminating1);
atexit (myProgramIsTerminating2);
//abort();
return 0;
}
Comentarios:
Si abort no está comentado: no se imprime nada y no se llamará al destructor de algún objeto.
Si se comenta abortar como se indicó anteriormente: se llamará a algún destructor de objetos, obtendrá el siguiente resultado:
función de
salida 2 función de salida 1
Las siguientes cosas suceden cuando un programa llama exit():
atexitfunción se ejecutantmpfilese eliminanLa abortfunción () envía la SIGABRTseñal al proceso actual; si no se detecta, el programa finaliza sin garantía de que los flujos abiertos se vacíen / cierren o que tmpfilese eliminen los archivos temporales creados mediante, no se invoquen atexitlas funciones registradas y el estado de salida cero se devuelve al host.
Desde la página de manual de exit ():
La función exit () provoca la finalización normal del proceso y el valor del estado & 0377 se devuelve al padre.
Desde la página del manual abort ():
Abort () primero desbloquea la señal SIGABRT, y luego eleva esa señal para el proceso de llamada. Esto da como resultado la finalización anormal del proceso a menos que se capture la señal SIGABRT y el controlador de señal no regrese.
abortenvía la SIGABRTseñal abortno vuelve a la persona que llama. El controlador predeterminado para la SIGABRTseñal cierra la aplicación. stdiolas secuencias de archivos se vacían y luego se cierran. Sin embargo, los destructores para instancias de clase C ++ no lo son (no estoy seguro en este caso, ¿quizás los resultados no están definidos?).
exittiene sus propias devoluciones de llamada, configuradas con atexit. Si se especifican devoluciones de llamada (o solo una), se invocan en el orden inverso al de su orden de registro (como una pila), entonces el programa se cierra. Al igual que con abort, exitno vuelve a la persona que llama. stdiolas secuencias de archivos se vacían y luego se cierran. Además, se llaman destructores para instancias de clase C ++.