当索引超出向量类的范围时,没有编译错误或运行时错误

No compilation error or run time error when index out of range of vector class?

本文关键字:编译 错误 运行时错误 范围 索引 向量      更新时间:2023-10-16

当我使用向量类时,我发现当索引超出向量范围时,没有编译错误或运行时错误。问题可以通过以下代码显示

#include <iostream>
#include <vector>
using namespace std;
int main(){
  vector<double> a(10,0.0);
  a[10]=10.0;
  cout<<"a[10]="<<a[10]<<"n";
  cout<<"size of a is "<<a.size()<<"n";
  return 0;
}

运行此代码的结果是

a[10]=10
size of a is 10

未报告错误。另一件需要注意的事情是,a.size()仍然返回10,尽管我可以成功访问a[10]

我的问题是,当试图索引超出向量范围时,有没有办法让程序报告错误?

这是设计使然。为了提供最大性能,operator[] 不会检查参数的有效性。就像裸数组一样,访问向量边界之外的元素会导致未定义的行为。

。虽然我可以成功访问a[10]...

这是未定义行为的允许表现。同样允许你的代码抛出异常,崩溃,通过所有测试,但随后在客户的脸上爆炸,发动核打击等。

您可以使用std::vector::at(index)进行边界检查访问。如果索引无效,它会抛出std::out_of_range

边界检查

与无边界检查不一定是一个全有或全无的命题:请参阅如何使 std::vector 的运算符[] 编译在 DEBUG 中进行边界检查,而不是在 RELEASE 和 Valgrind 等工具中进行边界检查。

在使用

[] 运算符访问元素之前,您必须使用 vector::at(index) 或手动检查范围。

使用[]时不检查范围会导致未定义的行为,请参阅其定义:

/**
 *  @brief  Subscript access to the data contained in the %vector.
 *  @param n The index of the element for which data should be
 *  accessed.
 *  @return  Read-only (constant) reference to data.
 *
 *  This operator allows for easy, array-style, data access.
 *  Note that data access with this operator is unchecked and
 *  out_of_range lookups are not defined. (For checked lookups
 *  see at().)
 */

at()

...
* @throw  std::out_of_range  If @a n is an invalid index.
...

补充一下其他人所说的话:

  1. 虽然可以在编译过程中检测到您提到的特定情况 - 这相对复杂,我不知道任何C++编译器实际上这样做。

  2. 如果您将g++与其libstdc++一起使用,则可以在#include指令之前添加以下内容。这将启用运行时边界检查(以及对 STL 容器的许多其他检查),即使您使用通常不检查的 [] 运算符:

    #define _GLIBCXX_DEBUG 1
    

开发/调试期间启用 #2 是个好主意。