Em C e C ++, qual é a diferença entre exit()
e abort()
? Estou tentando finalizar meu programa após um erro (não uma exceção).
Em C e C ++, qual é a diferença entre exit()
e abort()
? Estou tentando finalizar meu programa após um erro (não uma exceção).
Respostas:
abort()
sai do seu programa sem chamar funções registradas usando atexit()
primeiro e sem chamar primeiro os destruidores de objetos. exit()
faz as duas coisas antes de sair do seu programa. Porém, ele não chama destruidores para objetos automáticos. assim
A a;
void test() {
static A b;
A c;
exit(0);
}
Destruirá a
e b
corretamente, mas não chamará destruidores de c
. abort()
não chamaria destruidores de nenhum dos objetos. Como isso é lamentável, o Padrão C ++ descreve um mecanismo alternativo que garante a finalização adequada:
Objetos com duração de armazenamento automático são todos destruídos em um programa cuja função
main()
não contém objetos automáticos e executa a chamada paraexit()
. O controle pode ser transferido diretamente para issomain()
, lançando uma exceção capturadamain()
.
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);
}
}
Em vez de ligar exit()
, organize esse código throw exit_exception(exit_code);
.
abort envia um sinal SIGABRT, sair apenas fecha o aplicativo executando a limpeza normal.
Você pode manipular um sinal de aborto como desejar, mas o comportamento padrão é fechar o aplicativo também com um código de erro.
abort não executará a destruição de objetos de seus membros estáticos e globais, mas a saída o fará.
Obviamente, quando o aplicativo estiver completamente fechado, o sistema operacional liberará qualquer memória não liberada e outros recursos.
Tanto no cancelamento quanto no encerramento do programa de saída (assumindo que você não substituiu o comportamento padrão), o código de retorno será retornado ao processo pai que iniciou seu aplicativo.
Veja o seguinte exemplo:
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;
}
Comentários:
Se o cancelamento for descomentado: nada será impresso e o destruidor de algum objeto não será chamado.
Se abortar for comentado como acima: someobject destructor será chamado, você obterá a seguinte saída:
função de
saída 2 função de saída 1
O seguinte acontece quando um programa chama exit
():
atexit
função são executadastmpfile
são removidosA abort
função () envia o SIGABRT
sinal para o processo atual; se não for capturado, o programa será encerrado sem garantia de que os fluxos abertos sejam liberados / fechados ou que os arquivos temporários criados via tmpfile
sejam removidos, atexit
as funções registradas não sejam chamadas e uma função não- o status de saída zero é retornado ao host.
Na página do manual exit ():
A função exit () causa o encerramento normal do processo e o valor do status & 0377 é retornado ao pai.
Na página do manual abort ():
O abort () primeiro desbloqueia o sinal SIGABRT e, em seguida, gera esse sinal para o processo de chamada. Isso resulta na finalização anormal do processo, a menos que o sinal SIGABRT seja capturado e o manipulador de sinal não retorne.
abort
envia o SIGABRT
sinal. abort
não retorna ao chamador. O manipulador padrão para o SIGABRT
sinal fecha o aplicativo. stdio
os fluxos de arquivos são liberados e depois fechados. Destruidores para instâncias de classe C ++ não são, no entanto (não tenho certeza disso - talvez os resultados sejam indefinidos?).
exit
possui seus próprios retornos de chamada, definidos com atexit
. Se retornos de chamada forem especificados (ou apenas um), eles serão chamados na ordem inversa de sua ordem de registro (como uma pilha), e o programa será encerrado. Como com abort
, exit
não retorna ao chamador. stdio
os fluxos de arquivos são liberados e depois fechados. Além disso, os destruidores para instâncias de classe C ++ são chamados.