奇数无限循环

问题描述:

我在看另一个用户提交了一些代码段的问题。
此代码有一个循环尝试写入超出范围的数组索引,并且作为检查代码的一部分,我尝试编译并运行它。 (OP报告说它正在写入一个文件 - 这只是在超出边界循环之后的代码中)。奇数无限循环

我在一些printf()语句添加(是的,我知道,C++,使用std::cout,但我保持什么他们曾使用)来跟踪进度在运行时,那么我编译并运行它。

我没有输出。

这很奇怪,所以我删除了所有问题的循环。这是确切的代码,然后我跑:

#include <iostream> 
#include <cstdlib> 
#include <cstdio> 
#include <fstream> 

#define m 17 
#define n 17 
using namespace std; 


int main(){ 
    double f0[n][m],f[n][m],x[n],y[m]; 
    double dx, time, dy, dt, alpha, mstep, termx, termy, dd; 
    dx = 1.0; 
    dy = 1.0; 
    dt = 0.20; 
    alpha = 0.20; 
    mstep = 200; 
    FILE * mFile; 

    for(int j=0; j<m; j++){ 
     printf("running: j = %d\n",j); //***       I added this line 
     for(int i=0; i<n+1; i++){ 
      f0[i][j] = 0.0; 
      f[i][j] = 0.0; 
      if (i == n && j == m-1){ printf("Will this crash now?\n");}//I added this line 
     } 
    } 
    printf("made it out without crashing");       //I added this line 


    return 0; 
} 

我期待下面的输出(带有***注释行不存在在这一点上:

Will this crash now? 
Segmentation-fault... (blah blah blah) 

相反,没有什么,和控制没有公布
添加在***行,我再次运行程序:

... 
running: j = 1 
running: j = 2 
running: j = 3 
running: j = 4 
running: j = 5 
running: j = 1 
running: j = 2 
running: j = 3 
running: j = 4 
running: j = 5 
running: j = 1 
... 

这很奇怪。在for循环头文件中,除j++之外,应该没有j的分配,但它在某个时刻正在重置。

我编这跑了许多次的情况下,这是一个小故障,没有变化。然后,我运行了原始发布在question中的完整代码,但添加了额外的printf声明。
j周期现在从1变为15.

进一步的测试表明,代码的长度以某种方式改变了周期。

The code posted in this question: 33 lines, 1- 5 repeated. 
The original code posted:   98 lines, 1-15 repeated. 
Removing bottom two loops:  71 lines, 1-10 repeated. 

这是一个编译器错误好歹我是不是盲目的,做一些分配j的地方,完全丢失了吗?

任何人都可以重现吗?

编译器:在Cygwin下运行的GCC 4.8.2。

+1

'i 2014-11-03 16:30:00

+1

_“我知道这一点..”_我恐怕至少不是整个故事。 – 2014-11-03 16:34:15

+0

我的白痴时刻,当然内循环超出了每个外循环的界限......标记关闭。 – Baldrickk 2014-11-03 16:37:44

这个循环几乎肯定是错误的:

for(int i=0; i<n+1; i++){ 
     f0[i][j] = 0.0; 
     f[i][j] = 0.0; 

因为主要尺寸n,因此迭代你超出数组边界。

要么你想:

for(int i=0; i<n; i++){ 

,或者你需要使阵列尺寸增加1

否则未定义行为大就是这样 - 未定义。

+0

“这段代码有一个循环,试图写入一个超出界限的数组索引” – interjay 2014-11-03 16:29:39

+0

我认为这是问题的关键 - 他是故意这样做的。 – Barry 2014-11-03 16:29:46

+1

哦 - 我的坏 - 所以这个问题归结为“为什么没有未定义的行为做我想要的?” ? – 2014-11-03 16:30:36

根据您的支票,您认为只有在i == n && j == m-1之后才会出现超出界限的访问,但事实上它会在更早的时候发生。第一次出界出现的时候是j==0 && i==n。之后,所有投注都关闭。该程序可能会崩溃,进入无限循环,或者做其他事情。