gcc C++中向量和地址边界错误的更好运行时错误

8ehkhllq  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(123)

在Python中,当我们访问数组范围之外的索引时,我们会得到一个错误输出,它给出了代码中出现这个错误的确切位置:
第一个
但是,在C++中,这样的代码在GCC和Clang编译器中只会给我们一个一般的地址边界错误:

#include <vector>

int main(int argc, const char **argv) {
  std::vector<int> array{};
  int index = 0;
  int value = array[index];

  return 0;
}

在C++中,有没有一种方法可以更好地显示运行时错误,并提供更多详细信息?

zkure5ic

zkure5ic1#

只给予我们一个一般地址边界错误
不,它甚至不能保证能做到这一点。使用[]访问越界会导致C中的 undefined behavior。如果发生这种情况,你就失去了对程序行为的任何保证。它可能会失败并出现某种错误,但它也可能继续运行,产生错误的输出或做其他事情。这是必须理解的与Python的一个非常重要的区别。在C中如果你违反了语言规则或库函数的前提条件,编译器或程序将无法保证告诉你这一点。2在很多情况下,它的行为并不像预期的那样。
为了找出这样的错误是从哪里来的,你通常在调试器下运行你的程序,调试器会告诉你发生了分段错误(如果发生的话)的行,并允许你单步执行代码。
你可以保证,如果对std::vector进行越界索引时,使用它的.at成员函数而不是使用括号进行索引,将会生成一个错误消息。如果索引越界,将会抛出一个异常,你可以捕获该异常,或者让它传播到main之外,以终止程序并显示一些错误消息。但是,该异常通常不携带关于它被抛出的点的信息。同样,您需要在调试器下运行以获取该信息。
根据编译器和平台的不同,如果继续使用[],您也可以在编译程序时启用一个清理程序,当发生越界访问时,它将打印一个诊断信息,包括源代码行。例如GCC和Clang有一个地址清理程序,它可以在编译时使用-fsanitize=address来启用。还应添加选项-g,以生成将在清理程序输出中用于引用源位置的调试符号。

相关问题