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à ae bcorrettamente, 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():
atexitfunzione vengono eseguitetmpfilevengono rimossiLa abortfunzione () invia il SIGABRTsegnale 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 tmpfilevengano rimossi, atexitle 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.
abortinvia il SIGABRTsegnale. abortnon ritorna al chiamante. Il gestore predefinito per il SIGABRTsegnale chiude l'applicazione. stdioi 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?).
exitha 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, exitnon ritorna al chiamante. stdioi flussi di file vengono scaricati, quindi chiusi. Inoltre, vengono chiamati i distruttori per le istanze di classe C ++.