Как я могу немедленно закрыть программу на C?

#c #exit

#c #выход

Вопрос:

Я пишу код на языке Си, в котором анализирую некоторые данные. Я настроил программу на обработку только 100 входных данных. Когда он имеет более 100 входных данных, он выдает ошибку сегментации. Я хочу создать способ, при котором, когда количество входных данных превысит 100, пользователь будет предупрежден, и программа завершится. Я знаю, как сделать это из функции main простым return 0 способом, однако я нахожусь на расстоянии нескольких вызовов функций от main, и это трудно сделать, даже если a return 0 в этой функции будет поддерживать цикл.

Есть ли какой-нибудь немедленный способ завершить всю программу, не находясь в main?

Комментарии:

1. Вы можете использовать exit(int) from <stdlib.h> , но я думаю, вам стоит разобраться, почему ваша программа не может обрабатывать более 100 точек данных. Если только это не сделано специально или вы все равно не хотите, чтобы они это делали.

2. birryree правильно. Хотя можно внезапно выйти из любого места в программе, это крайне плохая практика (особенно если вы не очистили память, которая у вас есть в указателях и других объектах). Вам лучше корректно обрабатывать сценарий, в котором у них> 100 входных данных, и завершать работу с кодом ошибки, как только все будет очищено.

3. Теперь этот exit тег выглядит таким предвещающим…

4. @TheCapn вы знаете, что при выходе из программы вся память (как куча, так и стек) очищается автоматически? Я не видел действительно постоянной утечки памяти со времен Windows 98.

5. Вы не должны возвращать 0 из main, если ваша программа завершается с ошибкой. Если вы возвращаете ноль, вы сообщаете операционной системе, что прошли успешно. Лучше возвращать EXIT_FAILURE при сбое и EXIT_SUCCESS (0) только при успешном завершении программы.

Ответ №1:

Стандартная функция exit — это то, что вы ищете:

Завершает процесс в обычном режиме, выполняя регулярную очистку для завершения процессов.

Во-первых, все функции, зарегистрированные вызовами atexit, выполняются в порядке, обратном их регистрации. Затем все потоки закрываются, а временные файлы удаляются, и, наконец, управление возвращается в среду хоста.

Аргумент status возвращается в среду хоста.

Было бы лучше, если бы вы исправили ошибку segfault.

Комментарии:

1. Рассмотрим разницу между exit() и abort() — обработка atexit() .

Ответ №2:

Вам нужно включить стандартную библиотеку, а затем вы можете вызвать exit, где захотите:

 #include <stdlib.h>
...
exit(status);
 

где status — это целое число, представляющее код выхода.
Что касается статуса проблемы: для соглашения 0 — это успех, другие значения указывают на состояние ошибки.

Комментарии:

1. Стандарт предоставляет константы EXIT_SUCCESS и EXIT_FAILURE . Были машины, на которых любое четное число считалось успешным, в то время как нечетные значения были неудачными.

Ответ №3:

Вы также можете fprintf(stderr, ....) , а затем вызвать abort() ; это может быть полезно, если вы хотите позже отладить свою ошибку.

Но я считаю, что вам следует перекодировать свою программу так, чтобы ограничения по размеру определялись только доступными ресурсами: поэтому, если вы запускаете свою программу на гораздо большем компьютере (что бы это ни значило), она может обрабатывать более 100 входных данных.

Ответ №4:

Немного лучше было бы перехватить ошибку сегментации с помощью обработчика сигналов и заставить обработчик сигналов вызвать сигнал SIGSTOP.

Таким образом, ваша программа останавливается, но остается в памяти. Затем вы можете подключиться к ней с помощью отладчика и увидеть программу во всей ее красе, застывшую на месте в момент, когда произошел сбой SEGFAULT.

Это может быть полезно для поиска проблем в давно запущенных программах, которые вы не запускаете в среде разработки.

Комментарии:

1. Это правильный ответ. Не просто советуя исправить фактическую проблему, а с конструктивным советом о том, как это сделать. Конечно, это ответ только на POSIX, но все же…

2. @JerryJeremiah Это удобный трюк, который я использовал в некоторых типах систем, с дополнительным преимуществом, заключающимся в том, что если можно определить, почему segfault был вызван в первую очередь, и что исправление заключается в простом редактировании значения переменной (не всегда возможно), можно возобновить процесс впоследствии! Я также использовал его как способ выполнения других действий, таких как отправка сообщений «приостановить» другим процессам (иногда на других машинах) до вызова sigstop, чтобы полностью остановить всю инфраструктуру. Кроме того, в наши дни я являюсь поклонником signalfd — действительно хорошей вещи, которая есть в Linux в наши дни