В C и С++, в чем разница между exit()
и abort()
? Я пытаюсь закончить свою программу после ошибки (не исключение).
В чем разница между exit() и abort()?
Ответ 1
abort()
выходит из вашей программы без функций вызова, зарегистрированных с помощью atexit()
сначала и без вызова деструкторов объектов. exit()
выполняет оба действия перед выходом из вашей программы. Однако он не вызывает деструкторы для автоматических объектов. Так
A a;
void test() {
static A b;
A c;
exit(0);
}
Будет уничтожено a
и b
правильно, но не будет вызывать деструкторы c
. abort()
не будет называть деструкторы ни одного объекта. Поскольку это несчастливо, стандарт С++ описывает альтернативный механизм, который обеспечивает правильное завершение:
Объекты с автоматической продолжительностью хранения уничтожаются в программе, функция
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);
.
Ответ 2
прервать отправляет сигнал 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;
}
Комментарии:
-
Если прервать раскоментировано: ничего не печатается, и деструктор некоторого объекта не будет вызван.
-
Если прервать прокомментировано, как указано выше: будет вызван дескриптор someobject, вы получите следующий вывод:
функция выхода 2
функция выхода 1
Ответ 3
Следующие события происходят, когда программа вызывает exit
():
- Выполняются функции, зарегистрированные функцией
atexit
- Все открытые потоки очищаются и закрываются, файлы, созданные с помощью
tmpfile
, удаляются - Программа завершается с указанным кодом выхода на хост
Функция abort
() отправляет сигнал SIGABRT
в текущий процесс, если он не пойман, программа завершается без гарантии, что открытые потоки сбрасываются/закрываются или что временные файлы, созданные с помощью tmpfile
, являются удаленные, atexit
зарегистрированные функции не вызываются, и на хост возвращается не нулевой статус выхода.
Ответ 4
На странице выхода():
Функция exit() вызывает нормальное завершение процесса и значение статус и 0377 возвращается родительскому объекту.
На странице abort():
Функция abort() сначала блокирует сигнал SIGABRT, а затем повышает сигнал для вызывающего процесса. Это приводит к аномальному завершению процесса, если сигнал SIGABRT не пойман, и сигнал обработчик не возвращается.
Ответ 5
abort
отправляет сигнал SIGABRT
. abort
не возвращается к вызывающему абоненту. Обработчик по умолчанию для сигнала SIGABRT
закрывает приложение. stdio
потоки файлов очищаются, затем закрываются. Деструкторы для экземпляров класса С++, однако, (не уверены в этом - возможно, результаты undefined?).
exit
имеет свои собственные обратные вызовы, заданные с помощью atexit
. Если обратные вызовы заданы (или только один), они вызываются в порядке обратного порядка их регистрации (например, стек), затем программа завершает работу. Как и в случае с abort
, exit
не возвращается к вызывающему. stdio
потоки файлов очищаются, затем закрываются. Кроме того, вызываются деструкторы для экземпляров класса С++.