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á a
y b
correctamente, 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
():
atexit
función se ejecutantmpfile
se eliminanLa abort
función () envía la SIGABRT
señ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 tmpfile
se eliminen los archivos temporales creados mediante, no se invoquen atexit
las 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.
abort
envía la SIGABRT
señal abort
no vuelve a la persona que llama. El controlador predeterminado para la SIGABRT
señal cierra la aplicación. stdio
las 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?).
exit
tiene 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
, exit
no vuelve a la persona que llama. stdio
las secuencias de archivos se vacían y luego se cierran. Además, se llaman destructores para instancias de clase C ++.