exit()和abort()有什么区别?

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)

将破坏ab正确,但不会称为破坏者c.abort()不会调用两个对象的析构函数.由于这是不幸的,C++标准描述了一种确保正确终止的替代机制:

具有自动存储持续时间的对象在程序中被销毁,该程序的功能不main()包含自动对象并执行调用exit().可以main()通过抛出捕获的异常将控制直接转移到这样的a 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

而不是打电话exit(),而是安排代码throw exit_exception(exit_code);.

  • 据我所知,退出和中止之间的另一个区别是,中止可能(取决于操作系统配置)导致生成核心转储。 (3认同)
  • +1因为,虽然Brian R. Bondy很好,但你确实提出了中止/退出的问题(不是被称为堆栈对象的析构函数),并为RAII密集型C++进程提供了替代方案. (2认同)

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注册功能不叫,和非零退出状态将返回给主机.


str*_*ger 5

abort发送SIGABRT信号。 abort不会返回给调用者。SIGABRT信号的默认处理程序关闭应用程序。 stdio文件流被刷新,然后关闭。然而,C++ 类实例的析构函数不是(不确定这个——也许结果是未定义的?)。

exit有自己的回调,设置为atexit. 如果指定了回调(或仅指定了一个),则按照注册顺序的相反顺序(如堆栈)调用它们,然后程序退出。与abort,exit不会返回给调用者。 stdio文件流被刷新,然后关闭。此外,还会调用 C++ 类实例的析构函数。


Fed*_*oni 5

从exit()手册页:

exit()函数导致正常的进程终止,status&0377的值返回给父进程.

从abort()手册页:

abort()首先取消阻塞SIGABRT信号,然后为调用进程引发该信号.除非捕获SIGABRT信号且信号处理程序未返回,否则会导致进程异常终止.