Исключение исключений нарушения доступа?

Пример

int *ptr;
*ptr = 1000;

Могу ли я получить исключение нарушения доступа к памяти с использованием стандартного С++ без использования каких-либо специфических для Майкрософт.

Ответ 1

Неа. С++ не генерирует исключения, когда вы делаете что-то плохое, что может привести к поражению производительности. Такие вещи, как нарушения доступа или деление на нулевые ошибки, скорее напоминают "машинные" исключения, а не вещи на уровне языка, которые вы можете поймать.

Ответ 2

Прочтите и плачьте!

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

Магия случается, когда вы бросаете свое собственное исключение и обрабатываете это.

#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");

}

Ответ 3

Существует очень простой способ поймать любое исключение (деление на ноль, нарушение прав доступа и т.д.) в Visual Studio, используя блок try → catch (...). Достаточно небольшой настройки настроек проекта. Просто включите /EHa в настройках проекта. См. Свойства проекта → C/С++ → Генерация кода → Измените Исключительные исключения С++ на "Да с исключениями SEH" . Что это!

Подробнее см. здесь: http://msdn.microsoft.com/en-us/library/1deeycx5 (v = vs .80).aspx

Ответ 4

Этот тип ситуации зависит от реализации, и поэтому для ловушки потребуется конкретный механизм поставщика. С Microsoft это будет связано с SEH, а * nix будет включать в себя сигнал

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

Ответ 5

Как уже говорилось, для платформы Windows не существует способа поставщика Microsoft/компилятора. Однако, очевидно, полезно поймать эти типы исключений в обычном try {} catch (исключение ex) {} для сообщения об ошибках и более изящном выходе вашего приложения (как говорит JaredPar, теперь приложение, вероятно, находится в беде), Мы используем _se_translator_function в простой оболочке класса, которая позволяет нам улавливать следующие исключения в обработчике 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)

Оригинальный класс пришел из этой очень полезной статьи:

http://www.codeproject.com/KB/cpp/exception.aspx

Ответ 6

Не механизм обработки исключений, Но вы можете использовать механизм signal(), который предоставляется C.

> man signal

     11    SIGSEGV      create core image    segmentation violation

Запись на NULL-указатель, вероятно, вызовет сигнал SIGSEGV

Ответ 7

По крайней мере, для меня подход signal(SIGSEGV ...), упомянутый в другом ответе , не работал на Win32 с Visual С++ 2015. Для меня было использовать _set_se_translator(), найденный в eh.h. Он работает следующим образом:

Шаг 1) Убедитесь, что вы включили Да с исключениями SEH (/EHa) в свойствах проекта/С++/Генерация кода/включение исключений С++, как указано в ответе Владимира Фрицкого.

Шаг 2) Вызовите _set_se_translator(), передав указатель функции (или лямбда) для нового транслятора исключений. Он называется переводчиком, потому что он в основном просто берет исключение низкого уровня и перебрасывает его как нечто более легкое для поиска, например std::exception:

// 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();
};

Ответ 8

Подобное нарушение означает, что с кодом что-то серьезно не так, и это ненадежно. Я вижу, что программа может захотеть сохранить данные пользователя таким образом, чтобы надеяться, что они не будут писать поверх предыдущих данных, в надежде, что пользовательские данные еще не повреждены, но по определению нет стандартного метода от поведения undefined.