exit()
和abort()
有什么区别?我想在程序发生错误时(不是异常情况)结束程序。exit()
和abort()
有什么区别?我想在程序发生错误时(不是异常情况)结束程序。abort()
函数会在退出程序时不调用使用atexit()
注册的函数和对象析构函数,而exit()
函数在退出程序前会先调用它们。但是,exit()
函数不会调用自动变量的析构函数。
A a;
void test() {
static A b;
A c;
exit(0);
}
会正常销毁 a
和 b
,但不会调用 c
的析构函数。abort()
不会调用任何对象的析构函数。由于这很不幸,C++ 标准描述了一种替代机制来确保正确终止:
在一个程序中,只要其函数
main()
不包含自动对象并执行调用到exit()
的操作,所有具有自动存储期的对象都会被销毁。通过抛出一个在main()
中捕获的异常,可以直接将控制传输到这样的main()
。
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);
}
}
不要调用 exit()
,而是改为使用代码 throw exit_exception(exit_code);
。
abort 发送 SIGABRT 信号,exit 则只是正常关闭应用程序。
你可以按照自己的需求处理一个 abort 信号,但默认行为是使用错误代码关闭应用程序。
abort 不会执行静态和全局成员的对象析构,但 exit 会执行。
当应用程序完全关闭时,操作系统将释放任何未释放的内存和其他资源。
在 abort 和 exit 中,程序终止时(假设您没有覆盖默认行为),返回代码将返回给启动应用程序的父进程。
请参见以下示例:
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;
}
注释:
如果取消abort的注释:不会打印任何内容,并且someobject的析构函数将不会被调用。
如果像上面那样注释掉abort:someobject的析构函数将被调用,您将得到以下输出:
退出函数2
退出函数1
exit
()函数时会发生以下事情:
atexit
函数注册的函数将被执行tmpfile
创建的文件将被删除abort()
函数向当前进程发送SIGABRT
信号,如果未被捕获,则程序将终止,不保证打开的流被刷新/关闭或通过tmpfile
创建的临时文件被删除,不会调用atexit
注册的函数,同时向主机返回非零的退出状态。abort
发送 SIGABRT
信号。 abort
不会返回给调用者。 SIGABRT
信号的默认处理程序关闭应用程序。 stdio
文件流被刷新,然后关闭。但是,C++ 类实例的析构函数不会被调用(对此不确定结果是什么?)。
exit
有自己的回调函数,使用 atexit
设置。 如果指定了回调函数(或只有一个),它们以相反的注册顺序(像堆栈一样)调用,然后程序退出。 与 abort
一样,exit
不会返回给调用者。 stdio
文件流被刷新,然后关闭。此外,将调用 C++ 类实例的析构函数。
从exit()手册页面:
exit()函数导致正常进程终止,并将status & 0377的值返回给父进程。
从abort()手册页面:
abort()首先取消阻塞 SIGABRT 信号,然后为调用进程引发该信号。这会导致进程异常终止,除非捕获SIGABRT信号并且信号处理程序不返回。