I am writing a sapper on c ++. For storage of cells I use a two-dimensional dynamic array (I plan to later enter the user the size of the field). The cell is a structure. When you click on an empty cell, a recursive function (shw) is called, which checks the neighboring cells for emptiness, and if they are empty, opens them. At the first call, the function works as it should, but when recursively, it produces: "Unhandled exception at 0x000329C9 in project.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00202F40)."

#include <iostream> #include <ctime> using namespace std; int xy = 2; int bombs = 1; struct cell { bool bomb = false; int count = 0; bool show = false; bool flag = false; cell() { bomb = false; } }; int calc(cell** ar, int x, int y) { int sum = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (!(i == 0 && j == 0)) { if (x + i > -1 && y + j > -1 && x + i < xy && y + j < xy) { if (ar[x + i][y + j].bomb) sum++; } } } } return sum; } void shw(cell** ar, int x, int y) { for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (!(i == 0 && j == 0)) { if (x + i > -1 && y + j > -1 && x + i < xy && y + j < xy) { if (!ar[x + i][y + j].bomb && !ar[x + i][y + j].flag) { ar[x + i][y + j].show = true; shw(ar, x + i, y + j); } } } } } } void main() { srand(time(0)); int finds = 0; int shows = 0; cell** field = new cell*; for (int i = 0; i < xy; i++) field[i] = new cell[xy]; int rndx = 0, rndy = 0; int temp = 0; while (temp < bombs) { rndx = rand() % xy; rndy = rand() % xy; if (!field[rndx][rndy].bomb) { temp++; field[rndx][rndy].bomb = true; } } for (int i = 0; i < xy; i++) { for (int j = 0; j < xy; j++) { field[i][j].count = calc(field, i, j); } } for (int i = 0; i < xy; i++) { for (int j = 0; j < xy; j++) { if (!field[i][j].bomb) cout << field[i][j].count; else cout << "x"; if (field[i][j].flag && !field[i][j].bomb) cout << "!"; } cout << endl; } int mx = 0, my = 0; bool flag = false; while (!(finds == bombs || shows == (xy*xy - bombs))) { cout << "///////////////////////////////////////////////////////////////" << endl; for (int i = 0; i < xy; i++) { for (int j = 0; j < xy; j++) { if (field[i][j].show) cout << field[i][j].count; if (field[i][j].flag) cout << "!"; if (!field[i][j].show && !field[i][j].flag) cout << "?"; } cout << endl; } cin >> mx >> my >> flag; if (flag) { if (field[mx][my].show) field[mx][my].show = false; field[mx][my].flag = !field[mx][my].flag; } else { if (field[mx][my].bomb) { cout << endl << endl; for (int i = 0; i < xy; i++) { for (int j = 0; j < xy; j++) { if (!field[i][j].bomb) cout << field[i][j].count; else cout << "x"; if (field[i][j].flag && !field[i][j].bomb) cout << "!"; } cout << endl; } cout << "LOSE" << endl; system("pause"); return; } else { field[mx][my].show = true; shw(field, mx, my); } } finds = 0; for (int i = 0; i < xy; i++) { for (int j = 0; j < xy; j++) { if (field[i][j].bomb && field[i][j].flag) finds++; } } shows = 0; for (int i = 0; i < xy; i++) { for (int j = 0; j < xy; j++) { if (field[i][j].show && !field[i][j].flag) shows++; } } } cout << "VICTORY!" << endl; system("pause"); } 
  • Management in the console: (row number with 0) (column number with 0) (0 - press, 1 - put / remove the flag) - Denis
  • It is possible that the recursion is too deep, and the stack is not rubber, so it overflowed ... - Vladimir Martyanov
  • Have you seen the size of the field ?! 2x2 with one bomb. Maximum 3 function calls. And it lies already on the second call. - Denis
  • one
    See the debugger, what else can I say ... - Vladimir Martyanov

1 answer 1

You have very deep recursion with very low memory consumption. So, the problem is not in memory, as such, but in the wrong recursion.

For example, recursion without the condition of its completion.

What will happen when checking the cell from which you have already come? By code - nothing. You will open it, but in no way will you let your recursive function understand that you don’t need to call recursion for it. Those. you are doing infinite recursion ... Recursion always implies checking the condition that it is not needed further - otherwise wait for problems ...

Type - let's go to the right. Let's open. Now recursively let's go left. Let's open. Next - recursively let's go to the right ... Well, you understand, right?

  • Thank. Just added a check for the "openness" of the checked cell. - Denis