В чем разница между exit () и abort ()? - PullRequest
126 голосов
/ 29 декабря 2008

В C и C ++, в чем разница между exit() и abort()? Я пытаюсь завершить свою программу после ошибки (не исключение).

Ответы [ 5 ]

113 голосов
/ 29 декабря 2008

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); вместо.

32 голосов
/ 29 декабря 2008

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 не закомментировано: ничего не печатается и деструктор некоторого объекта не вызывается.

  • Если прокомментировать abort , как указано выше: будет вызван деструктор someobject, вы получите следующий вывод:

функция выхода 2
функция выхода 1

10 голосов
/ 29 декабря 2008

Когда программа вызывает exit (), происходит следующее:

  • Функции, зарегистрированные функцией atexit, выполняются
  • Все открытые потоки сбрасываются и закрываются, файлы, созданные tmpfile, удаляются
  • Программа завершается с указанным кодом выхода на хост

Функция abort () отправляет сигнал SIGABRT текущему процессу, если он не обнаружен, программа завершается без гарантии того, что открытые потоки сброшены / закрыты или временные файлы, созданные с помощью tmpfile удалено, atexit зарегистрированные функции не вызываются, и ненулевой статус выхода возвращается хосту.

5 голосов
/ 29 декабря 2008

со страницы руководства выхода ():

Функция exit () вызывает нормальное завершение процесса и значение статус & 0377 возвращается родителю.

со страницы руководства abort ():

Функция abort () сначала разблокирует сигнал SIGABRT, а затем повышает его сигнал для вызывающего процесса. Это приводит к ненормальному завершению процесса, если сигнал SIGABRT не пойман и сигнал обработчик не возвращает.

4 голосов
/ 29 декабря 2008

abort отправляет сигнал SIGABRT. abort не возвращается звонящему. Обработчик по умолчанию для сигнала SIGABRT закрывает приложение. stdio файловые потоки сбрасываются, затем закрываются. Деструкторы для экземпляров класса C ++, однако, не являются (не уверены в этом - возможно, результаты не определены?).

exit имеет свои собственные функции обратного вызова, установленные с помощью atexit. Если указаны обратные вызовы (или только один), они вызываются в порядке, обратном порядку их регистрации (например, в стеке), тогда программа завершается. Как и в случае abort, exit не возвращается к вызывающей стороне. stdio файловые потоки сбрасываются, затем закрываются. Также деструкторы для экземпляров класса C ++ вызываются.

...