В C и C ++ в чем разница между exit()
и abort()
? Я пытаюсь завершить программу после ошибки (не исключение).
В C и C ++ в чем разница между exit()
и abort()
? Я пытаюсь завершить программу после ошибки (не исключение).
Ответы:
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);
.
abort отправляет сигнал SIGABRT, 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
Когда программа вызывает exit
(), происходят следующие вещи :
atexit
функцией, выполняютсяtmpfile
, удаляютсяФункция abort
() отправляет SIGABRT
сигнал текущему процессу, если он не обнаружен, программа завершается без гарантии, что открытые потоки будут сброшены / закрыты или что временные файлы, созданные с помощью tmpfile
, удалены, atexit
зарегистрированные функции не вызываются, а не хосту возвращается нулевой статус выхода.
На странице руководства exit ():
Функция exit () вызывает нормальное завершение процесса, и значение status & 0377 возвращается родителю.
На странице руководства abort ():
Abort () сначала разблокирует сигнал SIGABRT, а затем вызывает этот сигнал для вызывающего процесса. Это приводит к ненормальному завершению процесса, если только сигнал SIGABRT не перехвачен и обработчик сигнала не вернется.
abort
посылает SIGABRT
сигнал. abort
не возвращается к вызывающему. Обработчик SIGABRT
сигнала по умолчанию закрывает приложение. stdio
файловые потоки сбрасываются, а затем закрываются. Однако деструкторов для экземпляров классов C ++ нет (не уверен в этом - возможно, результаты не определены?).
exit
имеет свои собственные обратные вызовы, установленные с помощью atexit
. Если обратные вызовы указаны (или только один), они вызываются в порядке, обратном порядку их регистрации (как стек), тогда программа завершается. Как и в случае abort
, exit
не возвращается к вызывающему. stdio
файловые потоки сбрасываются, а затем закрываются. Также вызываются деструкторы для экземпляров класса C ++.