2 cinccino Cinccino 于 2015.07.25 22:45 提问

滑雪问题因为全局变量产生的bug

谢谢大家的回答弱弱的题主已经明白了Orz

题目时经典的滑雪问题,最近帮别人查程序的时候看到的。

问题出在程序的第19行的变量tmpMax上。如果这个变量在函数体内声明,就是现在程序那样就不会有问题,但是如果将其定义为全局变量就会出问题。第一个出问题的地方是(2,3)点,我已经让程序在这里输出单步结果了。希望对C/C++熟悉的前辈能够解答一下这个问题,感激不尽!

debug中的代码如下:

 #include <iostream>
#include <stdio.h>
#include <memory.h>
//#include <conio.h>
using namespace std;
int skiing[110][110];
int done[110][110];
int R, C;
int Len = 0;
//int tmpMax;
int Ski(int a, int b){
    bool flag = false;
    if(a == 2 && b == 3){
        printf("dfs(%d %d)\n", a, b);
        flag = true;
    }
    //printf("dfs(%d %d)\n", a, b);
    if (done[a][b] != 0)
        return done[a][b];
    //tmpMax = 1    
    int tmpMax = 1;//警察叔叔就是这个变量!!!!
    if (a - 1 >= 1 && skiing[a - 1][b] < skiing[a][b]){
        int len = Ski(a - 1, b) + 1;
        if (len - tmpMax > 0){
            if(flag) printf("Len = %d  tmpMax = %d\n", len, tmpMax);
            tmpMax = len;
        }
        if(flag){
            printf("tmpMax = %d\n", tmpMax);
            printf("getlen(%d, %d) = %d\n\n", a-1, b, len);
        }
    }
    if (a + 1 <= R && skiing[a + 1][b] < skiing[a][b]){
        int len = Ski(a + 1, b) + 1;
        if (len - tmpMax > 0){
            if(flag) printf("Len = %d  tmpMax = %d\n", len, tmpMax);
            tmpMax = len;
        }
        if(flag){
            printf("tmpMax = %d\n", tmpMax);
            printf("getlen(%d, %d) = %d\n\n", a+1, b, len);
        }
    }
    if (b - 1 >= 1 && skiing[a][b - 1] < skiing[a][b]){
        int len = Ski(a, b - 1) + 1;
        if (len - tmpMax > 0){
            if(flag) printf("Len = %d  tmpMax = %d\n", len, tmpMax);
            tmpMax = len;
        }
        if(flag){
            printf("tmpMax = %d\n", tmpMax);
            printf("getlen(%d, %d) = %d\n\n", a, b-1, len);
        }
    }
    if (b + 1 <= C && skiing[a][b + 1] < skiing[a][b]){
        int len = Ski(a, b + 1) + 1;
        if (len - tmpMax > 0){
            if(flag) printf("Len = %d  tmpMax = %d\n", len, tmpMax);
            tmpMax = len;
        }
        if(flag){
            printf("tmpMax = %d\n", tmpMax);
            printf("getlen(%d, %d) = %d\n\n", a, b+1, len);
        }
    }

    done[a][b] = tmpMax;
    //printf("calc(%d %d) = %d\n", a, b, done[a][b]);
    return done[a][b];
}
int main(){
    cin >> R >> C;
    memset(skiing, 0, sizeof(skiing));
    memset(done, 0, sizeof(done));
    for (int i = 1; i < R + 1; ++i)
        for (int j = 1; j < C + 1; ++j)
            cin >> skiing[i][j];
    for (int i = 1; i < R + 1; ++i){
        for (int j = 1; j < C + 1; ++j){
            //done[i][j] = Ski(i, j);
            Ski(i, j);
            //cout << done[i][j] << " ";
            if (done[i][j] > Len)
                Len = done[i][j];
            //getch();
        }
        //cout << endl;
    }
    for (int i = 1; i < R + 1; ++i){
        for (int j = 1; j < C + 1; ++j){
            cout << done[i][j] << " ";
        }
        cout << endl;
    }
    cout << Len << endl;
    return 0;
}

4个回答

oyljerry
oyljerry   Ds   Rxr 2015.07.25 22:50

tmpMax全局变量的区别就是Ski函数每次进入都会拿到上次的值,而如果是局部变量就会每次进入函数都会重新初始化为1。这两个明显会导致结果不一样。

Cinccino
Cinccino 不不,当我定义成全局变量的时候也有在每次进函数体时对其初始化为1
2 年多之前 回复
caozhy
caozhy   Ds   Rxr 2015.07.25 23:07
Cinccino
Cinccino 感谢您的回答,但是您的结题报告好像没有提及关于全局变量的问题?题主的问题不是这道题的算法哦~
2 年多之前 回复
91program
91program   Ds   Rxr 2015.07.26 08:46

tmpMax 变量确实只有在函数 Ski 中使用,如果初始化的值是一样的,应该不会产生这样的问题。
现在出现问题,可能其它原因导致的,而不是这个变量是全局、还是局部变量的问题,虽然单从现象上看是它的原因。
所以,你需要了解算法后,再单步看看每一步是否是你想要的结果;找出是哪一句代码引起的问题,再分析吧。

walker_tang
walker_tang   2015.08.08 17:50

cin >> R >> C;
这里输入的R、C值是多少?如果是110,skiing、done两个数组就越界了。越界后会把后面挨着的变量踩掉。

Cinccino
Cinccino 已经找到问题了,不是越界,感谢回答!
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片