c++ - 越界访问数组不会出错,为什么?

标签 c++ arrays

我在 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 :未定义行为 .

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

通常,每当您遇到未定义的行为时,任何事情都可能发生。应用程序可能会崩溃,它可能会卡住,它可能会弹出您的 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/

    相关文章:

    c++ - c++/qt 中用于 google-drive 的 API 和工具

    c - 此 C 代码如何为多维数组的第一个索引生成正确的大小

    javascript - 如何在 Javascript 中对数组中的对象属性求和

    c - 如何在函数之间传递数组

    java - java中将整数数组分成不同大小的数组

    c++ - ‘)’ 标记之前预期有主表达式吗?错误

    c++ - C++ 中未命名命名空间的使用

    c++ - std::malloc 的奇怪段错误

    c++ - unique_ptr 到不透明结构? (C++)

    javascript - 如何设置全局数组