In C e C ++, qual è la differenza tra exit()
e abort()
? Sto cercando di terminare il mio programma dopo un errore (non un'eccezione).
In C e C ++, qual è la differenza tra exit()
e abort()
? Sto cercando di terminare il mio programma dopo un errore (non un'eccezione).
Risposte:
abort()
esce dal programma senza chiamare le funzioni registrate utilizzando atexit()
prima e senza prima chiamare i distruttori degli oggetti. exit()
fa entrambi prima di uscire dal programma. Tuttavia, non chiama i distruttori per gli oggetti automatici. Così
A a;
void test() {
static A b;
A c;
exit(0);
}
Distruggerà a
e b
correttamente, ma non chiamerà distruttori di c
. abort()
non chiamerebbe distruttori di nessuno degli oggetti. Poiché ciò è sfortunato, lo standard C ++ descrive un meccanismo alternativo che garantisce la terminazione corretta:
Gli oggetti con durata di memorizzazione automatica vengono tutti distrutti in un programma la cui funzione
main()
non contiene oggetti automatici ed esegue la chiamata aexit()
. Il controllo può essere trasferito direttamente a talemain()
gettando un'eccezione che viene catturatamain()
.
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);
}
}
Invece di chiamare exit()
, organizza throw exit_exception(exit_code);
invece quel codice .
abort invia un segnale SIGABRT, exit chiude semplicemente l'applicazione eseguendo la normale pulizia.
È possibile gestire un segnale di interruzione nel modo desiderato, ma il comportamento predefinito è chiudere anche l'applicazione con un codice di errore.
interruzione non eseguirà la distruzione oggetto del vostro statico e membri a livello mondiale, ma l'uscita volontà.
Naturalmente, quando l'applicazione è completamente chiusa, il sistema operativo libererà tutta la memoria non ordinata e altre risorse.
In entrambi abort e uscita terminazione del programma (supponendo che non si è ignorare il comportamento predefinito), il codice di ritorno sarà restituito al processo padre che ha avviato l'applicazione.
Vedi il seguente esempio:
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;
}
Commenti:
Se l' interruzione non viene scomposta: non viene stampato nulla e il distruttore di qualche oggetto non verrà chiamato.
Se l' interruzione viene commentata come sopra: verrà chiamato someobject destructor otterrai il seguente output:
funzione di uscita 2
funzione di uscita 1
Le seguenti cose accadono quando un programma chiama exit
():
atexit
funzione vengono eseguitetmpfile
vengono rimossiLa abort
funzione () invia il SIGABRT
segnale al processo corrente, se non viene rilevato il programma viene chiuso senza alcuna garanzia che i flussi aperti vengano scaricati / chiusi o che i file temporanei creati tramite tmpfile
vengano rimossi, atexit
le funzioni registrate non vengano chiamate e un lo stato di uscita zero viene restituito all'host.
Dalla pagina di manuale exit ():
La funzione exit () provoca la normale terminazione del processo e il valore di status & 0377 viene restituito al genitore.
Dalla pagina di manuale abort ():
Abort () prima sblocca il segnale SIGABRT, quindi genera quel segnale per il processo di chiamata. Ciò comporta l'interruzione anomala del processo a meno che il segnale SIGABRT non venga catturato e il gestore del segnale non ritorni.
abort
invia il SIGABRT
segnale. abort
non ritorna al chiamante. Il gestore predefinito per il SIGABRT
segnale chiude l'applicazione. stdio
i flussi di file vengono scaricati, quindi chiusi. I distruttori per le istanze di classe C ++ non sono tuttavia (non sei sicuro su questo - forse i risultati non sono definiti?).
exit
ha i suoi callback, impostati con atexit
. Se vengono specificati i callback (o solo uno), vengono chiamati nell'ordine inverso rispetto al loro ordine di registrazione (come uno stack), quindi il programma termina. Come con abort
, exit
non ritorna al chiamante. stdio
i flussi di file vengono scaricati, quindi chiusi. Inoltre, vengono chiamati i distruttori per le istanze di classe C ++.