Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как перехватить исключение, std::vector<int> test; test[-1]; 
:(
    Опции темы
neosapient
Дата 10.10.2014, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Здравствуйте.

Настроил проект на перехват исключений в настройках проекта:
  С\С++ -> Code Generation
  Enable C++ Exeption = Yes With SEH Exceptions (/EHa)

Тестирую обычное деление на 0 - исключение перехватывается.

Делаю более сложный тест: обращаюсь к -1 (минус первой) ячейке вектора
Код

#include <iostream>
#include <vector>

int main() {
    try{
        std::vector<int> arr;
        int val = arr[-1];
        std::cout << "successful";
    return 0;
    }catch(...)
    {
        std::cout << "exeption";
    }
}

И программа падает, а исключение перехватить не получается ((

P.S.
Прикрепил пример с программой к посту. (test_exeption.zip)
Использую Visual Studio 2008

P.P.S.
Для тех кто любит веб IDE, http://ideone.com/YaVxGX
Но исключений в этой веб IDE не возникает, так что для демонстраций она бесполезна

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  test_exeption.zip 3,12 Kb
PM MAIL   Вверх
sQu1rr
Дата 10.10.2014, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Ну так а кто сказал что исключение должно бросаться
http://www.cplusplus.com/reference/vector/...operator%5B%5D/
бросается тут: std::vector::at()
http://www.cplusplus.com/reference/vector/vector/at/
PM MAIL Skype GTalk   Вверх
neosapient
Дата 10.10.2014, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Хм, а что тогда происходит?
Там же (в глубинах std-библиотеки) нет exit(-1); ?

Программа вылетает - надо это как то перехватить.
Какие есть варианты?
PM MAIL   Вверх
sQu1rr
Дата 10.10.2014, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

то есть arr[-1] - вполне валидно, и вы сами должны проверять плохо это или хорошо. ваша программа вылетает, потому что visual studio шаманит с памятью, наделе же это UB
PM MAIL Skype GTalk   Вверх
neosapient
Дата 10.10.2014, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Может есть какие-либо флаги в настройке проекта, чтобы visual studio не шаманила с памятью?
Что значит аббревиатура UB?

Это сообщение отредактировал(а) neosapient - 10.10.2014, 15:41
PM MAIL   Вверх
sQu1rr
Дата 10.10.2014, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(neosapient @  10.10.2014,  15:36 Найти цитируемый пост)
Что значит аббревиатура UB?

http://lmgtfy.com/?q=UB+C%2B%2B

Цитата(neosapient @  10.10.2014,  15:36 Найти цитируемый пост)
Может есть какие-либо флаги в настройке проекта, чтобы visual studio не шаманила с памятью?

А может и не шаманит, я тончо не помню, может кто тут точно скажет. В любом случае, зачем вам это? почему бы просто не пользоваться at()? или сделать свой вектор в блекджеком и переопределенном операторе [] который вызывает at()
PM MAIL Skype GTalk   Вверх
DarthTon
Дата 10.10.2014, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 7.2.2009

Репутация: 1
Всего: 6



Цитата

И программа падает, а исключение перехватить не получается ((

Вы точно в релиз билде запускаете? А то в дебажном оно просто покажет assertion failed; это перехватывать не стоит. В релизном будет Access violation по адресу 0xFFFFFFFC(т.к. пустой вестор по-умолчанию инициализирует начальный указатель в 0) которое нормально ловится catch(...).
UD - undefined behavior. В общем случае поведение не определено, ибо arr[-1] фактически вернёт значение в ячейке которая находится перед ячейкой 0-го елемента вектора. А состояние той ячейки может быть каким-угодно.

В веб ИДЕ исключение не возникает потому что там оптимизирована строка "int val = arr[-1];" и она не исполняется на самом деле.
PM MAIL   Вверх
neosapient
Дата 10.10.2014, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



DarthTon,
Ни в дебаге, ни в релизе исключение в catch не ловится 
PM MAIL   Вверх
sQu1rr
Дата 10.10.2014, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(DarthTon @  10.10.2014,  16:05 Найти цитируемый пост)
которое нормально ловится catch(...)

С чего бы это?

Цитата(neosapient @  10.10.2014,  16:32 Найти цитируемый пост)
Ни в дебаге, ни в релизе исключение в catch не ловится  

Потому что С++ не генерирует исключения такие вещи. вы объясните что вы хотите реализовать
PM MAIL Skype GTalk   Вверх
korian
Дата 10.10.2014, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 2
Всего: 17



Цитата(neosapient @  10.10.2014,  14:13 Найти цитируемый пост)
Программа вылетает - надо это как то перехватить.
Какие есть варианты? 

я думаю в релизе не должна вылетать.
покрайней мере не на этой строчке. Потому шо это с точки зрения языка вполне нормальная законная операция, которая не подразумевает никаких ошибок. И врядли оно выделит память там, где в [-1] нельзя писать.
а segfault наверно в эксепшены не оборачивается, бо нормально восстановиться после такого нереально

Это сообщение отредактировал(а) korian - 10.10.2014, 16:50
PM   Вверх
DarthTon
Дата 10.10.2014, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 106
Регистрация: 7.2.2009

Репутация: 1
Всего: 6



Цитата

С чего бы это?

Ибо /Eha и Access violation. В этом случае crt функция FindHandlerForForeignException пытается найти catch(...) хендлер в списке SEH фреймов, и если находит, в этот хендлер передаётся Win32 исключение преобразованное к С++ исключению.
А вообще, что происходит при выполнение программы? Она падает? Где падает, с каким исключением?
PM MAIL   Вверх
Lukkoye
Дата 10.10.2014, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Вы хотите что то типа такого?

http://rextester.com/LGS53967

Код

#include <iostream>
#include <signal.h>
#include <vector>


void reaction_for_crash(const int signalnum);
void fnExit() {  puts ("User`s procedure of terminate process"); }

 void intercept_crash_state()
 {
    atexit(fnExit); 
    signal(SIGABRT, reaction_for_crash); 
    signal(SIGSEGV, reaction_for_crash);
    signal(SIGILL , reaction_for_crash);
    signal(SIGFPE , reaction_for_crash);
      
    #ifndef _MSC_VER
         signal(SIGBUS,  handle); 
    #endif
 }

int main()
{
    std::cout << "Hello, world!\n";
    
    intercept_crash_state();
    std::vector<int> arr;
    int val = arr[-1];
    std::cout << "successful";
}



void reaction_for_crash(const int signalnum)
{
    std::cout<<"crash_intercept!\n";
    std::cout<<"detected system exception: ";
    
    switch (signalnum)
    {
        case SIGABRT: std::cout<< "SIGABRT\n"; break;
        case SIGSEGV: std::cout<< "SIGSEGV\n"; break;
        case SIGILL:  std::cout<< "SIGILL\n" ; break;
        case SIGFPE:  std::cout<< "SIGFPE\n" ; break;
        #ifndef _MSC_VER
        case SIGBUS:  std::cout<< "SIGBUS\n" ; break;
        #endif
        default:      std::cout<< "UNKOWN\n" ; break;
    }
    
    signal(signalnum, SIG_DFL);  
    exit(3); 
}



Если вкратце, существует особый вид исключений: системные.

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

В этом случае система решает ликвидировать сбойное приложение, что бы оно не мешало нормальной работе всей системы в целом.

И посылает сбойному приложению сигнал. 

Некоторые сигналы приложение может обработать, и после этого даже остаться в живых.
После некоторых сигналов гибель приложения становится неизбежной. 
В этом случае система лишь уведомляет о неизбежном.

В общем почитайте о сигналах.

Так же рекомендую к прочтению о seh exception
https://ru.wikipedia.org/wiki/%D0%A1%D1%82%...%BD%D0%B8%D0%B9


Это сообщение отредактировал(а) Lukkoye - 10.10.2014, 18:40
PM MAIL   Вверх
neosapient
Дата 10.10.2014, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Lukkoye, спасибо за ответ.

Но обработчик исключения не сработал в программе собранной VC9.
Может надо флаги какие-нибудь включить?

P.S.
Цитата

Настроил проект на перехват исключений в настройках проекта:
  С\С++ -> Code Generation
  Enable C++ Exeption = Yes With SEH Exceptions (/EHa)

PM MAIL   Вверх
Lukkoye
Дата 10.10.2014, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(neosapient @  10.10.2014,  19:30 Найти цитируемый пост)
Lukkoye, спасибо за ответ.

Но обработчик исключения не сработал в программе собранной VC9.
Может надо флаги какие-нибудь включить?


Мне не очевидно, что именно вы имеете ввиду под "исключением". 




PM MAIL   Вверх
bsa
Дата 21.10.2014, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Если мне память не изменяет, то catch не ловит SEH исключения. Их ловит __catch.
В любом случае, ЛОВИТЬ ДАННЫЕ ИСКЛЮЧЕНИЯ НЕЛЬЗЯ. Если возникло такое исключение, то ты должен исправить его причину в программе, а не подставлять костыли по восстановлению дальнейшей работы программы. Так как не исключено, что дальнейшая работа просто невозможно.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1021 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.