为什么我可以设置数组范围之外的值?

Why can I set values outside of the array's range?

本文关键字:范围 我可以 设置 数组 为什么      更新时间:2023-10-16

据我所知,数组只能是固定大小,这是在创建它时定义的(如果您想创建与动态大小类似的东西,请使用向量代替)。

但是,当我尝试在数组外设置值时,我完全能够:

int badNums[5] = {4, 13, 14, 24, 34};
badNums[999] = -127;
std::cout << badNums[999] << std::endl;
// Returns -127

如果我试图访问固定范围之外的数组值,情况就更奇怪了:

std::cout << badNums[997] << std::endl;
// Returns 825245046 (but seems to be randomly chosen every time I run it)

这是怎么回事?

c++不执行边界检查,因为这会减慢速度。它不会阻止你使用数组外的数组下标(甚至是负数!),但是一旦你这样做了,你就会得到未定义的行为。

有时未定义行为似乎工作正常。但是不要被愚弄了,在你看不到的幕后可能会发生不好的事情。对您的示例做如下修改:

int badNums[5] = {4, 13, 14, 24, 34};
int sentinel = 0;
badNums[6] = -127;
std::cout << badNums[6] << sentinel << std::endl;

许多编译器上,您将看到sentinel已将值更改为-127,尽管由于这是未定义的行为,因此不能保证。

总之

你正在读取数组后面的内存。只要内存属于你(或进程),那就"完全可以"。

<标题>长(er)回答

当你创建一个数组时,你保留了一定的内存空间(在你的例子中是5*sizeof(int)(应该是~40byte))。当您试图访问越界(这是您正在做的事情的最新术语)的数据时,任何事情都可能发生。你很幸运,你正在访问内存,这属于你的进程,否则操作系统应该(也会)杀死你的进程,你会得到一个SEGFAULT。

一定要确保在数组边界内进行读写操作。其他的都可能导致不良的运行时行为。

<标题> 奖金

要检查是否越界访问,可以使用valgrind

valgrind ./yourProgram

,然后valgrind将打印每个访问,这是不应该做的

您在内存中为该值设置了一个位置,但是您没有告诉计算机为您的目的保留该位置。它可能被其他进程或您定义的其他变量覆盖。

正如其他人所说,如果内存已经被其他程序保留,也可能出现不可预测的行为。

badNums[997]*((badNums)+(997))相同
您正在尝试访问一些内存,其中内容可能是任何东西。
可以是其他程序使用的旧值,也可以是您的程序使用的值。
这会导致未定义的行为。