У 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);замість цього.
аборт надсилає сигнал SIGABRT, вихід просто закриває програму, виконуючи звичайну очистку.
Ви можете обробляти сигнал переривання, як хочете, але поведінка за замовчуванням - це закрити програму, а також кодом помилки.
аборт не буде виконувати знищення об'єктів ваших статичних і глобальних членів, але вихід буде.
Звичайно, якщо програма повністю закрита, операційна система звільнить незапалену пам'ять та інші ресурси.
В обох переривання і вихід завершення програми (якщо ви не перевизначити поведінку за замовчуванням), код повернення буде повернений в батьківський процес , який почав свій додаток.
Дивіться наступний приклад:
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;
}
Коментарі:
Якщо аборт не коментується: нічого не друкується і деструктор якогось об'єкта не буде викликаний.
Якщо аборт буде прокоментовано як вище: буде викликано якийсь деструктор об'єкта, ви отримаєте такий вихід:
функція виходу 2
функція виходу 1
Коли програма викликає exit(), відбувається таке:
atexitфункцією, виконуютьсяtmpfile, видаляютьсяФункція abort() надсилає SIGABRTсигнал поточному процесу, якщо його не зафіксували, програма припиняється без гарантії, що відкриті потоки змиваються / закриваються або tmpfileвидаляються тимчасові файли через , atexitзареєстровані функції не викликаються, а не- нульовий статус виходу повертається хосту.
З сторінки керівництва exit ():
Функція exit () викликає нормальне завершення процесу, і значення статусу & 0377 повертається батьківському.
З сторінки посібника про переривання ()
Аборт () спочатку розблокує сигнал SIGABRT, а потім піднімає цей сигнал для процесу виклику. Це призводить до ненормального припинення процесу, якщо сигнал SIGABRT не зачеплений і обробник сигналу не повернеться.
abortпосилає SIGABRTсигнал. abortне повертається до абонента. Обробник за замовчуванням для SIGABRTсигналу закриває програму. stdioпотоки файлів промиваються, потім закриваються. Однак деструктори для екземплярів класу C ++ не є (не впевнені в цьому - можливо, результати не визначені?).
exitмає свої зворотні дзвінки, встановлені з atexit. Якщо зворотні виклики вказані (або лише один), вони викликаються в порядку, зворотному їх порядку реєстрації (як стек), тоді програма виходить. Як і у випадку abort, exitне повертається до абонента. stdioпотоки файлів промиваються, потім закриваються. Також викликаються деструктори для екземплярів класу C ++.