当数组出局时,是否通过异常检查安全?

时间:2015-10-16 22:53:05

标签: c++ arrays c++11 error-handling indexoutofboundsexception

这是我的代码:

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()吗?

3 个答案:

答案 0 :(得分:6)

只需添加边界检查。

C ++不对数组进行边界检查,更不用说抛出异常了。

使用vectors / std :: array,您可以使用.at()方法而不是[]运算符来进行检查。

最后,GSL引入了array_view,它允许您添加&#34;零成本注释&#34;这样分析工具就可以进行边界检查。尚未出现GSL事实上的标准实施。另见:

答案 1 :(得分:3)

没有

当只从数组中读取时,异常检查可能没问题(但不是很优雅)。

然而,在写作时,你冒着被覆盖的风险&#34;外国&#34;内存,这是一个巨大的安全风险,加上它可能会通过覆盖堆栈帧来改变执行流程,谁知道什么 - 也就是说,即使实际上预期会抛出异常处理程序也会运行

最好的决定是检查每次迭代的索引。 鉴于您提到了assert,我想您确实知道要开始的数组维度。

答案 2 :(得分:3)

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 ++不会对原始(C)数组进行边界检查,并且operator[]实现中的任何标准库类型都没有,所以如果m是一个在这些类型中,您将永远不会抛出异常。相反,STL类型提供at()方法,如果需要进行边界检查,则应使用该方法。