Answers:
abort()
退出程序而无需先调用使用其注册的函数atexit()
,也无需首先调用对象的析构函数。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);
。
中止发送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;
}
注释:
如果取消注释abort:不打印任何内容,并且不会调用某对象的析构函数。
如果中止的注释如上:将调用someobject析构函数,您将获得以下输出:
退出功能2
退出功能1
程序调用exit
()时会发生以下情况:
atexit
执行功能注册的功能tmpfile
删除创建的文件在abort
()函数发送SIGABRT
信号到电流过程中,如果它没有被捕获该程序终止于不能保证打开的流被刷新/闭合或经由创建的临时文件tmpfile
被移除,atexit
注册功能不叫,和非零退出状态返回到主机。
从exit()手册页:
exit()函数导致正常进程终止,并且状态&0377的值返回给父级。
在abort()手册页中:
abort()首先取消阻止SIGABRT信号,然后为调用过程引发该信号。除非捕获到SIGABRT信号并且信号处理程序不返回,否则这将导致过程异常终止。
abort
发送SIGABRT
信号。 abort
不返回到呼叫者。SIGABRT
信号的默认处理程序将关闭应用程序。 stdio
文件流被刷新,然后关闭。但是,没有C ++类实例的析构函数(不确定这一点-可能结果不确定吗?)。
exit
有自己的回调,设置为atexit
。如果指定了回调(或仅指定一个),则以与注册顺序相反的顺序(如堆栈)调用它们,然后程序退出。与一样abort
,exit
不会返回到调用方。 stdio
文件流被刷新,然后关闭。同样,将调用C ++类实例的析构函数。