因为某些原因,循环继续

时间:2015-08-27 23:21:09

标签: c++ loops for-loop

#include <iostream>

using namespace std;

int main()
{
    int lists[30];
    lists[30] = 30;
    lists[0] = 31;
    cout << lists[30];
    cout << "\n";
    cout << lists[0];
    for(int a = 0; a < lists[30]+lists[0]; a++)
    {
        cout << "\n";
        cout << lists[2];
    }
}

在for循环之后,它应该只显示列表[2]的值61次;列表[30] = 30并列出[0] = 31,所以组合它们是61. for循环中的表达式是否有效?它似乎永远循环。

3 个答案:

答案 0 :(得分:5)

使用lists[29],您超出了数组的范围。记住索引是从0开始的,而不是从1开始的。

默认情况下,C ++没有对数组进行边界检查,因此:

int array[100];
array[100] = 1;

与:

相同
int* array = calloc( 100, 4 );
*(array + 100) = 1;

...这是内存中数组边界之外的+1元素。您正在未分配的空间中写入,导致未定义的行为。

答案 1 :(得分:2)

{{1}}的有效索引是0到29.但是你正在访问30.由于这是未定义的行为,可能会发生各种奇怪的事情。

在您的情况下可能发生的事情是,其他一些操作(例如后续调用cout)正在使用该内存位置。因此,当您的循环运行时,该值不再是30。

答案 2 :(得分:0)

您的代码的基本问题是您正在使用未定义的内存位置,列表[30],因为您声明了一个包含30个元素的数组,但是解决了数组的第31个位置。 C和C ++都开始从零(0)开始索引数组,因此数组中实际的最后有效位置是30-1 = 29,因此列表[30]是无效的内存位置。

因为您在堆栈上声明了一个额外的变量a(与放置列表[30]的内存位置相同),并且您的编译器将该变量放在与数组相邻的内存中,所以在分配时列出[30]对于变量a的值,您还使用(无效的)内存位置列表[30]更改您要寻址的值(这取决于您的编译器在声明时选择放置变量的位置,因此该程序可能会以不同的方式运行不同的架构)。

#include <iostream>

using namespace std;

int main()
{

此行定义了一个30 int的数组,其有效索引为0..29

    int lists[30];

希望您的计划有效吗?将上面的数字30更改为31

    int lists[30+1];

或者,你至少可以通过在列表[30]和a,

之间的堆栈上放置另一个变量来使变量成为可行的
    int filler;

这一行解决了一个无效的位置,索引30,它是'stack'上与list [29]相邻的位置,并为该内存位置赋值

    lists[30] = 30;
    lists[0] = 31;

您认为列表[2]包含什么价值?

这一行代表一个无效的位置,索引30,这次引用该位置的内存

    cout << lists[30];
    cout << "\n";
    cout << lists[0];

然而,列表[30]无效,与以前一样的问题。由于int a在堆栈上分配,因此列出

    for(int a = 0; a < lists[30]+lists[0]; a++)
    {
        cout << "\n";

您尚未为列表[2]分配值,您认为该值是什么?

        cout << lists[2];
    }
}

数组索引的相同问题会出现在零索引的任何语言中,并且不会检查数组边界。