8 ответов:
Неа. C++ не исключение, когда вы делаете что-то плохое, что приведет к уменьшению производительности. Такие вещи, как нарушения доступа или деление на ноль ошибок, больше похожи на "машинные" исключения, а не на языковые вещи, которые вы можете поймать.
читай и плачь!
Я понял. Если вы не бросаете из обработчика, обработчик просто продолжит работу, а также исключение.
магия происходит, когда вы бросаете собственное исключение и обрабатываете его.
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <tchar.h> void SignalHandler(int signal) { printf("Signal %d",signal); throw "!Access Violation!"; } int main() { typedef void (*SignalHandlerPointer)(int); SignalHandlerPointer previousHandler; previousHandler = signal(SIGSEGV , SignalHandler); try{ *(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place. } catch(char *e) { printf("Exception Caught: %s\n",e); } printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n"); printf("But please kids, DONT TRY THIS AT HOME ;)\n"); }
существует очень простой способ поймать любое исключение (деление на ноль, нарушение доступа и т. д.) в Visual Studio С помощью try - > catch (...) блок. Достаточно незначительной настройки параметров проекта. Просто включите параметр /EHa в настройках проекта. Смотрите свойства проекта - > C / C++ - > генерация кода - > измените исключения Enable C++ на "Да с исключениями SEH". Вот так!
посмотреть детали здесь: http://msdn.microsoft.com/en-us/library/1deeycx5 (v = vs. 80). aspx
этот тип ситуации зависит от реализации и, следовательно, для ловушки потребуется конкретный механизм поставщика. С Microsoft это будет включать SEH, а *nix будет включать сигнал
В общем, хотя ловить исключение нарушения прав доступа очень плохая идея. Там почти нет способа, чтобы восстановить из AV исключения и попытка сделать это просто приведет к труднее найти ошибки в вашей программе.
как указано, на платформе windows нет способа сделать это без поставщика Microsoft / компилятора. Однако, очевидно, полезно поймать эти типы исключений в обычном try { } catch (exception ex) { } способе сообщения об ошибках и более изящном выходе вашего приложения (как говорит JaredPar, приложение теперь, вероятно, в беде). Мы используем _se_translator_function в простой оболочке класса, которая позволяет нам поймать следующие исключения в обработчике a try:
DECLARE_EXCEPTION_CLASS(datatype_misalignment) DECLARE_EXCEPTION_CLASS(breakpoint) DECLARE_EXCEPTION_CLASS(single_step) DECLARE_EXCEPTION_CLASS(array_bounds_exceeded) DECLARE_EXCEPTION_CLASS(flt_denormal_operand) DECLARE_EXCEPTION_CLASS(flt_divide_by_zero) DECLARE_EXCEPTION_CLASS(flt_inexact_result) DECLARE_EXCEPTION_CLASS(flt_invalid_operation) DECLARE_EXCEPTION_CLASS(flt_overflow) DECLARE_EXCEPTION_CLASS(flt_stack_check) DECLARE_EXCEPTION_CLASS(flt_underflow) DECLARE_EXCEPTION_CLASS(int_divide_by_zero) DECLARE_EXCEPTION_CLASS(int_overflow) DECLARE_EXCEPTION_CLASS(priv_instruction) DECLARE_EXCEPTION_CLASS(in_page_error) DECLARE_EXCEPTION_CLASS(illegal_instruction) DECLARE_EXCEPTION_CLASS(noncontinuable_exception) DECLARE_EXCEPTION_CLASS(stack_overflow) DECLARE_EXCEPTION_CLASS(invalid_disposition) DECLARE_EXCEPTION_CLASS(guard_page) DECLARE_EXCEPTION_CLASS(invalid_handle) DECLARE_EXCEPTION_CLASS(microsoft_cpp)в оригинальный класс пришел из этой очень полезной статьи:
по крайней мере для меня
signal(SIGSEGV ...)подход, упомянутый в другом ответе не работал на Win32 с Visual C++ 2015. Что сделал работа для меня была в использовании_set_se_translator()нашли вeh.h. Это работает следующим образом:Шаг 1) убедитесь, что вы включить да с исключениями SEH (/EHa) на Свойства Проекта / C++ / Генерация Кода / Включение Исключений C++, как указано в ответе Владимир Фрицкий.
Шаг 2) вызов
_set_se_translator(), передавая указатель функции (или лямбда) для нового исключения переводчик. Он называется транслятором, потому что он в основном просто берет исключение низкого уровня и повторно бросает его как что-то более легкое для захвата, напримерstd::exception:#include <string> #include <eh.h> // Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation; _set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) { std::string error = "SE Exception: "; switch (u) { case 0xC0000005: error += "Access Violation"; break; default: char result[11]; sprintf_s(result, 11, "0x%08X", u); error += result; }; throw std::exception(error.c_str()); });Шаг 3) поймать исключение, как обычно:
try{ MakeAnException(); } catch(std::exception ex){ HandleIt(); };
Не механизм обработки исключений , Но вы можете использовать механизм signal (), который предоставляется C.
> man signal 11 SIGSEGV create core image segmentation violationзапись в нулевой указатель, вероятно, вызовет сигнал SIGSEGV
такое нарушение означает, что с кодом что-то серьезно не так, и это ненадежно. Я вижу, что программа может попытаться сохранить данные пользователя таким образом, чтобы никто не надеялся записать предыдущие данные, в надежде, что данные пользователя еще не повреждены, но по определению нет стандартного метода борьбы с неопределенным поведением.
Comments