Исключение 0xC0000005 не обнаружено [дубликат]

Новые кодеры иногда пишут такой код:

my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...

Затем кодер остается с кучей именованных переменных с усилием кодирования O ( m * n ), где m - это число именованных переменных, а n - это количество раз, к которому необходимо получить доступ к группе переменных (включая создание) , Более проницательный новичок отмечает, что единственная разница в каждой из этих строк - это число, которое изменяется на основе правила и решает использовать цикл. Тем не менее, они зациклились на том, как динамически создавать эти имена переменных, и могут попробовать что-то вроде этого:

for i in range(10):
    my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)

Вскоре они обнаруживают, что это не сработает.

Если программа требует произвольных переменных «имена», лучше всего подходит словарь, как объясняется в других ответах. Однако, если вы просто пытаетесь создать много переменных, и вы не возражаете ссылаться на них с последовательностью целых чисел, вы, вероятно, ищете list. Это особенно верно, если ваши данные однородны, например, ежедневные показания температуры, еженедельные оценки викторины или сетка графических виджета.

Это можно собрать следующим образом:

my_calculator.buttons = []
for i in range(10):
    my_calculator.buttons.append(tkinter.Button(root, text=i))

Этот list также может быть создан в одной строке с пониманием:

my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]

Результат в любом случае - это заполненный list, с первым элементом, к которому обращаются с помощью my_calculator.buttons[0], следующего с my_calculator.buttons[1] и т. д. Имя переменной «base» становится именем list, и для доступа к нему используется различный идентификатор.

Наконец, не забудьте другие структуры данных, такие как set - это аналогично словарю, за исключением того, что каждое «имя» не имеет привязанного к нему значения. Если вам просто нужна «сумка» объектов, это может быть отличным выбором. Вместо этого:

keyword_1 = 'apple'
keyword_2 = 'banana'

if query == keyword_1 or query == keyword_2:
    print('Match.')

У вас будет следующее:

keywords = {'apple', 'banana'}
if query in keywords:
    print('Match.')

Используйте последовательность list для последовательности похожих объектов, a set для произвольного - помещенный пакет предметов или dict для мешка с именами со связанными значениями.

73
задан Ahmed Said 19 January 2009 в 14:27
поделиться

8 ответов

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

33
ответ дан unwind 22 August 2018 в 10:10
поделиться
  • 1
    Я знаю, что это исключения HW, но есть ключевые слова для Microsoft, которые обрабатывают это (__ try __except)? – Ahmed Said 19 January 2009 в 14:35
  • 2
    @Ahmed: да, но если вы их используете, «невозможное» может случиться. Например, некоторые из операторов после могут быть уже выполнены AV-строка кода или заявления перед тем, как AV не выполнил. – Aaron 19 January 2009 в 20:55
  • 3
    См. Мой ответ ниже, как включить обработку исключений с помощью регулярного блока try ... catch в VC ++. – Volodymyr Frytskyy 15 October 2013 в 20:35
  • 4
    @Aaron вы можете подробно остановиться на «невозможных вещах». часть? это из-за инструкций по переупорядочиванию компилятора и / или процессора? – Weipeng L 25 June 2018 в 22:00

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

7
ответ дан Damien 22 August 2018 в 10:10
поделиться
  • 1
    Я вижу, что использование компилятора Microsoft рассматривается как незаконная инструкция или нарушение прав доступа. Интересно. – David Thornley 19 January 2009 в 16:38

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

-1
ответ дан David Thornley 22 August 2018 в 10:10
поделиться
  • 1
    Возможно восстановление из-за нарушения прав доступа. Восстановление из EIP-перехода, никогда не возможно, если вы не изворотливы и не держите указатели инструкций уровня сборки. Тем не менее, нарушение доступа к доступу подходит для нереста другого процесса для функции создания отчетов об ошибках. – Петър Петров 11 September 2013 в 16:37

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

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

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

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

}
92
ответ дан Dukeling 22 August 2018 в 10:10
поделиться
  • 1
    wow не знал , что ! – jrharshath 17 June 2009 в 10:55
  • 2
    Хороший совет, особенно потому, что __try / __ кроме этого не поймает AV. – Fabio Ceconello 6 April 2011 в 17:32
  • 3
    +1 только для строки комментария открытия – Jamie Cook 8 February 2012 в 00:29
  • 4
    @Fabio: конечно __try / __, кроме как поймать AVs – Frederik Slijkerman 9 November 2012 в 13:08
  • 5
    Это НЕ работает в gcc, но работает в VC ++, но только в & quot; Debug & quot; строить. Тем не менее, для интересного решения. Обработчик сигнала будет вызываться, но исключение не будет выбрано. – Nathan Adams 22 September 2013 в 18:05
  • 6
    – Martin York 31 July 2015 в 15:57
  • 7

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

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

7
ответ дан JaredPar 22 August 2018 в 10:10
поделиться
  • 1
    Итак, ваш совет - знать, что является причиной исключения AV, не так ли? – Ahmed Said 19 January 2009 в 14:37
  • 2
    Абсолютно. AV представляют собой ошибку в вашем коде, и перехват исключения просто скроет проблему. – JaredPar 19 January 2009 в 14:59
  • 3
    Чтобы уточнить, стандарт C ++ проводит различие между неопределенными, неопределенными и реализованными реализациями. Определенная реализация означает, что реализация должна указывать, что происходит. Код в вопросе не определен, что означает, что все может случиться и быть разным каждый раз. – KeithB 19 January 2009 в 15:27
  • 4
    Улавливание доступа - это неплохая идея - это хорошо для пользователя. Тем не менее, единственная значимая вещь, которую я делаю в этом случае, - это создать другой процесс с помощью GUI Reporting GUI и попытаться создать текущий дамп процесса. Нерест процесс всегда успешный. Затем я делаю TerminateProcess () для самоубийства. – Петър Петров 11 September 2013 в 16:34
  • 5
    Плохая идея поймать исключение и молча игнорировать его. Это очень хорошая идея, когда можно поймать исключение и записать информацию о состоянии приложения для диагностических целей. Я как-то написал пользовательский интерфейс для бэкэнд-графической библиотеки, которая нуждалась в некоторой отладке. Каждый раз, когда он разбивался, люди приходили ко мне, потому что знали, что я написал пользовательский интерфейс. Я положил ловушку sig вокруг бэкэнда, который вытащил предупреждение, которое сообщило пользователю, что библиотека разбилась. Люди стали ходить к автору библиотеки. – Kent 4 November 2014 в 02:32

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

> man signal

     11    SIGSEGV      create core image    segmentation violation

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

3
ответ дан Martin York 22 August 2018 в 10:10
поделиться

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

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

Шаг 2) Вызовите _set_se_translator(), передав указатель функции (или лямбда) для нового исключения 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();
};
6
ответ дан Nadu 22 August 2018 в 10:10
поделиться

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

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

58
ответ дан Volodymyr Frytskyy 22 August 2018 в 10:10
поделиться
  • 1
    В Visual Studio .NET 2003 такого значения параметра нет, есть только «Нет». и «Да (/ EHsc)». Можете ли вы уточнить, какую минимальную версию Visual Studio вам нужно включить эту настройку? – izogfif 28 July 2014 в 18:30
  • 2
    Ссылка, как представляется, указывает «Visual Studio 2005». – Drew Delano 29 July 2015 в 22:37
  • 3
    что если с gcc или MinGW? – user1024 14 August 2018 в 03:24
Другие вопросы по тегам:

Похожие вопросы: