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



下面是我的代码:

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

只需添加边界检查。

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

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

最后,GSL引入了array_view,它允许您添加"零成本注释",以便分析工具可以进行边界检查。目前还没有出现GSL的实际标准实现。参见:

  • https://www.youtube.com/watch?v=1OEu9C51K2A

No.

当只从数组中读取时,异常检查可能是可以的(但一点也不优雅)。

然而,当写入时,您可能会覆盖"外部"内存,这是一个巨大的安全风险,加上它可能会通过覆盖堆栈帧来改变执行流,谁知道会发生什么——也就是说,在某些情况下,即使异常处理程序实际上预计会抛出,它也不会运行。

最好的决定是在每次迭代时检查索引。考虑到您提到的assert ing,我想你确实知道数组的尺寸。

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()方法,如果需要进行边界检查,您应该使用该方法。

最新更新