Безопасна ли проверка по исключению, когда массив выходит за пределы?

Вот мой код:

template<class T>
void Matrix<T>::set(const int i, const int j, const T v) {
try {
m[i][j] = v;
} catch (std::exception& e) {
std::cout << "Standard exception: " << e.what() << std::endl;
}
}

Но я в безопасности здесь? Я имею в виду, возможно, что i и / или j выходят за границы, но программа получает ошибку сегментации, будет ли выброшено исключение?

Если это не очень хороший подход, то я должен использовать assert() может быть?

1

Решение

Нет.

Проверка исключений может быть приемлемой (но не элегантной) при чтении только из массива.

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

Лучшее решение — проверять индексы на каждой итерации.
Учитывая, что вы упомянули assertВ общем, я полагаю, вы знаете размеры массива для начала.

3

Другие решения

Просто добавьте проверки границ.

C ++ не выполняет проверку границ массивов, не говоря уже об исключениях.

С векторами / std :: array вы можете использовать .at() метод вместо [] Оператор, чтобы получить проверку.

Наконец, GSL представляет array_view который позволяет добавить «аннотацию с нулевой стоимостью», чтобы инструменты анализа могли выполнять проверку границ. Де-факто стандартная реализация GSL еще не появилась. Смотрите также:

6

template<class T>
void Matrix<T>::set(const int i, const int j, const T v) {
try {
m[i][j] = v;
} catch (std::exception& e) {
std::cout << "Standard exception: " << e.what() << std::endl;
}
}

Вы не упоминаете, какой тип m есть, но при условии, что это пользовательский тип, который выполняет проверку границ в operator[]тогда ты должен быть в порядке. Проверка границ будет (или должна) произойти, и должно быть выдано исключение, до Любая попытка написать за границей.

Но обратите внимание, что C ++ не выполняет проверки границ для массивов raw (C), и ни один из стандартных типов библиотек в их operator[] реализации, так что если m это один из этих типов, то вы никогда не получите исключение. Вместо этого типы STL обеспечивают at() метод, который вы должны использовать вместо этого, если желательна проверка границ.

3
По вопросам рекламы [email protected]