127 c c++ error-handling exit abort
在C和C++中,exit()
和之间有什么区别abort()
?我试图在错误后结束我的程序(不是例外).
Joh*_*itb 114
abort()
退出程序而不调用atexit()
首先使用注册的函数,而不先调用对象的析构函数.exit()
在退出程序之前都做了.它不会为自动对象调用析构函数.所以
A a;
void test() {
static A b;
A c;
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
将破坏a
和b
正确,但不会称为破坏者c
.abort()
不会调用两个对象的析构函数.由于这是不幸的,C++标准描述了一种确保正确终止的替代机制:
具有自动存储持续时间的对象在程序中被销毁,该程序的功能不
main()
包含自动对象并执行调用exit()
.可以main()
通过抛出捕获的异常将控制直接转移到这样的amain()
.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
而不是打电话exit()
,而是安排代码throw exit_exception(exit_code);
.
Bri*_*ndy 32
abort发送SIGABRT信号,退出只关闭执行正常清理的应用程序.
您可以根据需要处理中止信号,但默认行为是关闭应用程序以及错误代码.
abort不会对静态成员和全局成员执行对象破坏,但是会退出.
当然,虽然当应用程序完全关闭时,操作系统将释放任何不同的内存和其他资源.
在中止和退出程序终止时(假设您没有覆盖默认行为),返回代码将返回到启动应用程序的父进程.
请参阅以下示例:
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;
}
Run Code Online (Sandbox Code Playgroud)
评论:
如果取消注释中止:不打印任何内容,并且不会调用someobject的析构函数.
如果abort如上所述进行注释:将调用someobject析构函数,您将获得以下输出:
退出功能2
退出功能1
Rob*_*ble 10
程序调用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信号且信号处理程序未返回,否则会导致进程异常终止.