最后一行执行后的堆栈错误

时间:2014-03-08 02:24:27

标签: c++ visual-c++ c++11

所以我有这个功课要做,我认为这样做很容易和快速但是我一直得到这个奇怪的堆栈错误在最后一行代码执行后,控制台上会显示正确的分数。任务是使用两个函数创建一个迷你战舰游戏,我生成一个4x4阵列随机放置6个内部,其余为零。之后,用户enter code here被问到x,y组合,直到他找到所有6个,最多10次尝试。这是代码:

#include <iostream>;
#include <string>;
#include <fstream>;

using namespace std;

const int DIMENSION = 4;



void creerGrille(int(&grilleNavale)[DIMENSION][DIMENSION]){


    //On remplit le tableau avec des zeros
    for (int i = 0; i <= 4; i++){
        for (int j = 0; j <= 4; j++){

            grilleNavale[i][j] = 0;

        }
    }


    //On place 6 "1"
    int i, j;//i et j seront les positions generes aleatoirement
    int k = 0;//k est une variable d iterations

    while(k <= 6) {//On ne connait pas le nombres d executions

        //On genere une position aleatoire
        i = rand()%7;
        j = rand()%7;

        ///On verifie que la case ne comporte pas deja un "1"
        ///Sinon on pourrait en placer moins que 6 en placant deux fois le meme 
        if (grilleNavale[i][j] != 1){

            grilleNavale[i][j] = 1;
            k++;

        }

    }//Fin while(k <= 6)


}//Fin creerGrille


/**
*  Genere un tableau 4x4 ou toutes les cellules contiennent un "0"
*  expecte six qui contiennent un "1". Les positions des cellules
*  qui contiennent des "1" sont determinees aleatoirement
*  \param
*  \param [out] grilleNavale: tableau de int de dimension 4x4
*  \return
*/
bool estValide(int x, int y, int(&grilleNavale)[DIMENSION][DIMENSION], int& score){

    if (grilleNavale[x][y] == 1){

        score++;
        grilleNavale[x][y] = 0;

        return true;//Puisque le coup etait valide

    }

    else{
        return false;
    }

}//Fin estValide


int main(){


    int nCoups = 0;
    int score = 0;
    int grilleNavale[DIMENSION][DIMENSION];
    creerGrille(grilleNavale);

    cout << "BATAILLE NAVALE ARGGGH\nVous allez entrez des coordonnes"
            "en (x,y) avec x et y comprit en 0 et 3";

    int x, y;
    bool estAcceptable;


    while ((score<6) && (nCoups<10)){


        cout << "\n\n\nEntrez les coodonnes de vote prochain coup"
            " x et y doivent etres en 0  et 3";

        //On valide les coordonnees entrees au clavier
        do{

            cout << "\n\nx = ";
            cin >> x;


            estAcceptable = ((x >= 0) && ( x <= 3));

            if (!estAcceptable){
                cout << "\nErreur position invalide\n";
            }

        } while (!estAcceptable);

        do{

            cout << "y = ";
            cin >> y;


            estAcceptable = ((y >= 0) && (y <= 3));

            if (!estAcceptable){
                cout << "Erreur position invalide\n";
            }

        } while (!estAcceptable);

        bool touche = estValide(x, y, grilleNavale, score);

        if (touche){
            cout << "\nARRRGHHH, touche";
        }
        else{
            cout << "\nFloushhh";
        }

        nCoups++;

    }//Fin while



    int scoreFinal = score;

    if (scoreFinal == 6){
        cout << "\n\nBravo, vous avez gagne !";
    }

    else{

        cout << "\n\nPouenpouenpouen, vous avez perdu, votre score: "
             << scoreFinal<<endl;   
    }


}//Fin main

(抱歉留下了法语文档,但我认为这是一个非常简单的程序。

1 个答案:

答案 0 :(得分:3)

creerGrille的输入数组有4行和列,但是你循环遍历[0,4],意味着访问边界元素。

for (int i = 0; i <= 4; i++){     // should be < 4
    for (int j = 0; j <= 4; j++){ // should be < 4

由于您使用的是C ++,我建议将功能更改为

void creerGrille( std::array<int, std::array<int, DIMENSION>, DIMENSION>& grilleNavale);

是的,这非常详细,但您可以使用typedef来减少击键次数。您还需要在调用代码中进行相应的更改。初始化数组元素的循环也可以用std::fill_n替换。

但我们还没有完成!前面还有更多问题

i = rand()%7;
j = rand()%7;

这将导致ij的值在[0,6]范围内,并且您正在使用这些值来索引前面提到的数组。再次,这是超出边界的元素访问,因此是未定义的行为。

此外,您不应该在现代C ++代码中使用rand()。看一下<random>标题及其为随机数生成提供的更好的设施。