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