我在C++程序中分配值,如下所示:

#include <iostream>
using namespace std;
int main()
{
    int array[2];
    array[0] = 1;
    array[1] = 2;
    array[3] = 3;
    array[4] = 4;
    cout << array[3] << endl;
    cout << array[4] << endl;
    return 0;
}

该程序将打印34。这应该是不可能的。我正在使用g++ 4.3.3

这是编译并运行命令
$ g++ -W -Wall errorRange.cpp -o errorRange
$ ./errorRange
3
4

仅当分配array[3000]=3000时,它才给我带来分段错误。

如果gcc不检查数组边界,我如何确定我的程序是否正确,因为它以后可能会导致一些严重的问题?

我用上面的代码替换了
vector<int> vint(2);
vint[0] = 0;
vint[1] = 1;
vint[2] = 2;
vint[5] = 5;
cout << vint[2] << endl;
cout << vint[5] << endl;

而且这也不会产生错误。

最佳答案

欢迎使用每个C / C++程序员最好的 friend : Undefined Behavior

由于多种原因,语言标准中没有指定很多内容。这就是其中之一。

通常,每当遇到 undefined 的行为时,任何事情都可能发生。该应用程序可能会崩溃,可能冻结,可能弹出您的CD-ROM驱动器或使恶魔从您的 Nose 中冒出来。它可能会格式化硬盘或将所有色情内容通过电子邮件发送给祖母。

即使您真的很倒霉,它似乎也可以正常工作。

该语言只是说如果您访问数组范围内的元素会发生什么。如果您超出范围,将会发生什么,这是不确定的。它现在似乎可以在您的编译器上运行,但是它不是合法的C或C++,并且不能保证它在下次运行该程序时仍然可以运行。或者它甚至还没有覆盖基本数据,而您只是还没有遇到过会引起问题的问题。

至于为什么没有边界检查,答案有几个方面:

  • 数组是C的剩余部分。C数组与原始数组差不多。只是具有连续地址的一系列元素。没有边界检查,因为它只是公开原始内存。在C.
  • 中几乎不可能实现强大的边界检查机制
  • 在C++中,可以对类类型进行边界检查。但是,数组仍然是老式的C兼容数组。这不是一个类。此外,C++还建立在另一个使边界检查不理想的规则上。 C++的指导原则是“您不为不使用的商品付费”。如果您的代码是正确的,则不需要边界检查,也不必强制您支付运行时边界检查的开销。
  • 因此,C++提供了std::vector类模板,该模板同时允许两者。 operator[]旨在提高效率。语言标准不要求执行边界检查(尽管也不禁止)。 vector 还具有at()成员函数,可以保证执行边界检查。因此,在C++中,如果使用 vector ,则可以兼得两全。您无需边界检查即可获得类似数组的性能,并且可以在需要时使用边界检查访问。
  • 关于c++ - 超出范围访问数组不会出错,为什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64106133/

    10-11 23:07
    查看更多