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

时间:2008-12-29 03:21:37

标签: c++ c error-handling exit abort

在C和C ++中,exit()abort()之间有什么区别?我想在错误之后结束我的程序(不是例外)。

5 个答案:

答案 0 :(得分:113)

abort()退出程序而不先调用使用atexit()注册的函数,而不先调用对象的析构函数。 exit()在退出程序之前完成这两项任务。它不会为自动对象调用析构函数。所以

A a;
void test() { 
    static A b;
    A c;
    exit(0);
}

会正确破坏ab,但不会调用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);

答案 1 :(得分: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;
}

评论:

  • 如果取消注释 abort :不打印任何内容,并且不会调用someobject的析构函数。

  • 如果 abort 被评论如上:将调用someobject析构函数,您将获得以下输出:

  

退出功能2
  退出功能1

答案 2 :(得分:10)

当程序调用{​​{1}}()时会发生以下情况:

  • 执行exit功能注册的功能
  • 刷新并关闭所有打开的流,删除由atexit创建的文件
  • 程序以指定的退出代码终止到主机

tmpfile()函数将abort信号发送到当前进程,如果没有捕获,则程序终止,不保证打开流被刷新/关闭或通过创建的临时文件删除SIGABRT,不调用tmpfile个注册函数,并向主机返回非零退出状态。

答案 3 :(得分:5)

从exit()手册页:

  

exit()函数导致正常的进程终止和值   现状与0377将返回给父母。

从abort()手册页:

  

abort()首先取消阻塞SIGABRT信号,然后提高它   呼叫过程的信号。除非捕获SIGABRT信号和信号,否则这会导致过程异常终止   处理程序不会返回。

答案 4 :(得分:4)

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

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