Как завершить программу в C ++ - PullRequest
       2

Как завершить программу в C ++

3 голосов
/ 02 сентября 2010

При выходе из программы на C ++ происходит сбой с ошибками, такими как:

EAccessViolation with mesage 'Access violation at address 0...

and

Abnormal Program Termination

Возможно, это вызвано каким-то деструктором, потому что это происходит только при выходе из приложения.Я использую несколько внешних библиотек и не могу найти код, который его вызывает.Существует ли функция, которая принудительно завершает работу программы (что-то вроде kill в Linux), чтобы операционная система освобождала память?Я мог бы использовать эту функцию в событии выхода из приложения.

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

Я просто спрашиваю из чистого любопытства, поэтому, пожалуйста, не давайте мне -1:)

Я пытался exit(0) из stdlib, но это не помогло.

РЕДАКТИРОВАТЬ:

Спасибо за ваши многочисленные ответы :) Я использую Builder C ++ 6 (я знаюэто устарело, но по некоторым причинам я должен был использовать это).Мое приложение использует библиотеку для нейронных сетей (FANN).Используя отладчик, я обнаружил, что программа аварийно завершает работу:

~neural_net()
{
    destroy();
}

destroy () несколько раз вызывает другую функцию fann_safe_free (ptr), то есть:

#define fann_safe_free(x) {if(x) { free(x); x = NULL; }}

Библиотека работает отлично, проблемапоявляется только тогда, когда это делает уборку.Вот почему я спросил о столь жестоком решении.Мое приложение многопоточное, но другие потоки работают с другими данными.

Я буду анализировать свой код в n-й раз (ошибка должна быть где-то), спасибо за все ваши советы:)

Ответы [ 8 ]

7 голосов
/ 02 сентября 2010

Вы должны решить проблему.

  • Первый шаг: найти при проверке все функции, которые вы регистрируете с помощью atexit () (надеюсь, не так много)
  • Второй шаг: найти все глобальные переменные и проверить их деструкторы.
  • Третий шаг: найти все переменные статической функции и проверить их деструкторы.

Но в противном случае вы можете прервать.
Примечание: отмена для Abnormal завершения программы.

abort()

Разница: (обратите внимание, что приложение оставляет основную функцию эквивалентной функции exit ())

  • Выход ()

    1. Вызывать функции, зарегистрированные с помощью функции atexit (3), в обратном порядке их регистрации. Это включает в себя уничтожение всех глобальных (статическая длительность хранения) переменных.
    2. Сброс всех открытых выходных потоков.
    3. Закрыть все открытые потоки.
    4. Отключить все файлы, созданные с помощью функции tmpfile (3).
  • прервать ()

    1. Сброс всех открытых выходных потоков.
    2. Закрыть все открытые потоки.
4 голосов
/ 02 сентября 2010

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

Почему бы вам не использовать отладчик и не попытаться выяснить, что является причиной ошибки?

Если ваше приложение является многопоточным, вы должны убедиться, что все потоки правильно закрыты перед выходом из приложения.Это довольно распространенная причина ошибки такого типа при выходе, когда фоновый поток пытается использовать память / объекты, которые уже были разрушены.

Редактировать:

на основе вашего обновленного вопроса, У меня есть следующие предложения:

Попытайтесь выяснить более конкретно, что вызывает сбой в деструкторе.

Первое, что я хотел бы сделать, это убедиться, что он не пытается уничтожитьNULL объект.Когда вы получаете сбой в ~ neural_net в своем отладчике, проверьте указатель «this», чтобы убедиться, что он не равен NULL.Если это так, то проверьте свой стек вызовов и посмотрите, где он разрушается, и сделайте проверку, чтобы убедиться, что он не равен NULL перед вызовом delete.

Если это не NULL, тогда я разверну этот макрос в destroy, так что вы можете увидеть, падает ли он при вызове бесплатно.

2 голосов
/ 02 сентября 2010

Вы можете попробовать позвонить abort(); (объявлено в <stdlib.h> и <process.h>)

Однако версия в VisualC ++ будет выводить предупреждающее сообщение при выходе: " Это приложение запросило среду выполнения, чтобы завершить его необычным способом. Для получения дополнительной информации обратитесь в службу поддержки приложения. «

1 голос
/ 03 сентября 2010

Вы пробовали ужасный шаг за шагом?Если ваш проект / решение просто слишком велико, возможно, вы можете попробовать сегментировать его, предполагая, что вы используете модульную сборку и тестируете каждый компонент по отдельности.Боюсь, без всякого кода или видимых деструкторов я могу дать вам абстрактный совет.Но, тем не менее, я надеюсь, что попытка свести к минимуму поле отладки поможет каким-то образом.

Удачи в получении ответа:)

1 голос
/ 02 сентября 2010

В Linux / UNIX вы можете использовать _exit:

#include <unistd.h>
void _exit(int status);

Функция _exit() похожа на exit(), но не вызывает никаких зарегистрированных функцийс atexit() или on_exit().Сбрасывает ли он стандартные буферы ввода / вывода и удаляет временные файлы, созданные с помощью tmpfile(3), зависит от реализации.С другой стороны, _exit() закрывает открытые файловые дескрипторы, и это может привести к неизвестной задержке, ожидающей завершения ожидаемого вывода.Если задержка нежелательна, может быть полезно вызвать такие функции, как tcflush() перед вызовом _exit().Отменяется ли ожидающий ввод-вывод и может ли быть отменен ожидающий ввод-вывод при _exit(), зависит от реализации.

0 голосов
/ 03 сентября 2010

Если вы используете Linux, valgrind должен решить вашу проблему. но если это Windows, попробуйте один из них: MemoryValidator, BoundsChecker или другие подобные инструменты.

Просто закрыть приложение - не лучший способ справиться с ошибками ...

0 голосов
/ 02 сентября 2010

Скорее всего, это происходит из-за обращения к нулевому указателю.В зависимости от вашей ОС попробуйте получить трассировку стека и определить виновника, а не просто выйти.

0 голосов
/ 02 сентября 2010

Этот немедленный выход из программы (и да, это ужасное решение) отменяется ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...