В 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 ++.