Как обработать исключение, которое возникает при попытке инициализировать значение за пределами массива, или при чтении из-за его пределов. Пробовал в catch писать "exception e", но оно не ловит.
если это встроенный c++
массив то можно ставить ассерты перед каждым доступом к его элементу -
#define array_size 100
int v[array_size];
int i = 100;
assert(i >= 0 && i < array_size); // бросит исключение
v[i] = 123;
если у вас std::vector
то как уже сказали в комментариях - воспользоваться функцией членом std::vector::at
которая гарантированно бросит исключение при выходе за пределы вектора.
std::vector<float> v(5);
v.at(5) = 1.0f; // бросит исключение
На самом деле в случае выхода за границу массива происходит исключение уровня операционной системы, после чего программе присылается сигнал об этом, и она падает (в комментариях меня поправят, если это не так, но общий смысл такой). Корректная реакция на такие сигналы - завершение программы, поскольку они вызываются недопустимыми операциями и после них программа может не находится в консистентном состоянии.
Однако, если очень хочется, то можно такую ошибку отловить и продолжить работу (при этом следует очень хорошо понимать зачем и почему понадобилось так делать, поскольку затея эта целиком и полностью не здоровая).
В основе обработки таких ошибок лежат функции setjmp
и longjmp
, позволяющие сохранить состояние программы и вернутся к сохраненному ранее состоянию. Так же нужно отловить сигнал операционной системы, что делается везде по-своему (Для POSIX
-систем достаточно обычных обработчиков сигналов, для windows
стоит использовать Structured Exception Handling
или Vectored Exception Handling
).
Итак. Регистрируем обработчик (пример для POSIX
).
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = signalHandler;
sigaction(SIGSEGV, &act, 0);
В обработчике сигнала возвращаемся к сохраненному состоянию и передаем не нулевое значение в качестве возвращаемого для setjmp
:
jmp_buf env;
static void signalHandler(int signum) {
longjmp(env, 1);
}
Перед входом в опасный блок сохраняем состояние программы:
try {
if (setjmp(env))
throw std::runtime_error("Some shit");
// Действия, которые могут уронить программу
Ловим брошенное исключение:
} catch (std::runtime_error & e) {
// Что-то делаем
}
Как оно работает. Функция setjmp
при сохранении возвращает 0
- исключение не кидается. Если дальше происходит ошибка, то longjmp
возвращает выполнение к setjmp
, которое в этот момент вернет 1
- бросится исключение, которое можно обработать.
Данный пример дает лишь общее представление о логике обработки таких ошибок, для использования его на практике, его стоит доработать. Более полное описание чего куда и зачем можно найти тут: Habrahabr: Обработка многократно возникающих SIGSEGV-подобных ошибок
Имеется небольшой класс для создания массива обернутого в shared_ptr, при запуске возникает ошибка : "Невозможно преобразовать int* в int", не могу...
Пытаюсь изменить значение текстового поля из другого потока, но почему-то не работает( Имеется класс MyThread:
Простой код с использованием MPIПри сборке в релиз отладка останавливается в указанном месте на ветке else
Написал вот такие две функции для нахождения длины строки и разбиение ее на лексемыКак можно еще оптимизировать данный код, не используя...