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

时间:2015-06-03 21:23:52

标签: c++ arrays c++11

根据我的阅读,数组只能是固定大小,在创建时定义(如果你想创建类似于动态大小的东西,则使用向量)。

但是,当我尝试在数组外部设置值时,我完全可以:

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)

这里发生了什么?

4 个答案:

答案 0 :(得分:2)

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

有时未定义的行为出现才能正常工作。不要被愚弄,可能会在幕后发生一些你无法看到的坏事。对你的例子稍作修改:

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

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

答案 1 :(得分:1)

简而言之

您正在读取阵列后面的内存。只要内存属于你(r进程),这就是“非常好”。

长(呃)回答

创建数组时,您需要保留一定的内存空间(在您的情况下为5 * sizeof(int)(应为~40byte))。当您尝试访问超出界限的数据时(这是您正在做的事情的正确术语),一切都可能发生。你很幸运,你正在访问属于你的进程的内存,否则操作系统应该(并且会)杀死你的进程,你将得到一个SEGFAULT。

始终确定,您正在读取和编写数组边界内部。其他一切都可能导致糟糕的运行时间行为。

加成

要检查,如果您正在访问越界,则可以使用valgrind

valgrind ./yourProgram

然后valgrind将打印每次访问,不应该这样做。

答案 2 :(得分:0)

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

正如其他人所说的那样,如果已经保留了内存,那么也可能存在不可预测的行为,例如另一个程序。

答案 3 :(得分:0)

badNums[997]*((badNums)+(997))相同。您尝试访问内容可能是任何内容的内存。
可能是某个其他程序使用的旧值,可能是程序使用的值。
这会导致不确定的行为。