循环中的数组行为

Jom*_*jes 4 c++

我是这个论坛的新手,我想问为什么我这个阵列的行为与我预期的不同?

int main() {
    int array[8]={3,5,5,6,6,5,3,5};
    for(int i=-1;i<=8;i+=2) {
        std::cout<<array[i+1];
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出结果为:35637

我不知道为什么结果是这样的,尤其是索引8中的最后一部分,即值为7 ...

Bar*_*ast 7

您的数组有8个条目,具有以下位置:

array[8] = {3, 5, 5, 6, 6, 5, 3, 5}
            ^  ^  ^  ^  ^  ^  ^  ^
 (position) 0  1  2  3  4  5  6  7 
Run Code Online (Sandbox Code Playgroud)

你的循环从每次开始i = -1,直到i <= 8,并且i每次增加2,因此i取值-1,1,3,5和7.因为你正在访问元素array[i+1],所以你要求位置0处的元素, 2,4,6和8.但是没有位置8,所以这是一个错误,程序的行为通过包含它而变得不确定,这意味着即使在与非法调用本身不同的地方,任何事情都可能发生(这显然是非常糟糕,必须始终避免).

在您的情况下,您的程序似乎正在读取数组结束后的内存中的任何内容.你偶然得到了一个7 - 那里可能有任何东西,实际上你的程序甚至可能不被允许访问那个内存,在这种情况下它会因分段错误而崩溃.

  • "所以这实际上正在读取阵列结束后内存中的任何东西",这是粗心的.行为未定义; 而已.例如,实现可能会限制对最后一个元素的越界访问; 特别是考虑到指针没有衰减. (3认同)
  • @Bathsheba我同意*可能*发生任何事情,但我认为很清楚*这里发生的*是一些额外的垃圾内存正在从数组末尾读取.我认为提问者描述他们为什么观察他们所做的行为会更有帮助,而不是这个程序在抽象机器上运行的行为.不过,你当然是正确的,我会编辑以使UB更清晰. (2认同)
  • 虽然我们在这里,但我想指出_"并且程序的行为在之后变得不确定"_是不正确的.整个程序的行为是未定义的(技术上没有"事后") - 编译器可以自由地假设这不会发生,所以它可能会[非常意外的优化](https://blogs.msdn.microsoft.com/oldnewthing/ 20140627-00/p = 633).是的,这不会发生在这里,但它需要警惕. (2认同)