根据我的阅读,数组只能是固定大小,在创建时定义(如果你想创建类似于动态大小的东西,则使用向量)。
但是,当我尝试在数组外部设置值时,我完全可以:
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)
这里发生了什么?
答案 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))
相同。您尝试访问内容可能是任何内容的内存。
可能是某个其他程序使用的旧值,可能是程序使用的值。
这会导致不确定的行为。