В чем разница между exit() и abort()?

В C и С++, в чем разница между 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 потоки файлов очищаются, затем закрываются. Кроме того, вызываются деструкторы для экземпляров класса С++.