2D Array printing gives "stack smashing detected"

I'm getting an error in that says:
" stack smashing detected: ./a.out terminated
Segmentation fault (core dumped) "
after the 2D Array prints in the boardInt() function. The array prints fine,
but I'm not sure why it breaks afterwards. I checked for a bounds issue in the for loop, but I don't see a problem with them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <ios>
#include <iomanip>

using namespace std;

enum Spaces {BLANK = 1, RED, BLUE}; //Spaces on the gameboard

void StudentInfo(){	
}

void GameInfo(){
        cout << setfill('-') << setw(72) << "" << endl;
        cout << "Input game info" << endl;
        cout << setfill('-') << setw(72) << "" << endl;
}

void BoardInt(Spaces gameBoarded[][6], int rowSized){
        cout << "\nInitializing game board...\n" << endl;

        for(int i = 0;i < rowSized; ++i){
                for(int j = 0;j < 6; ++j){
                        gameBoarded[i][j] = BLANK;
                        cout << gameBoarded[i][j] << " ";
                }
                cout << endl;
        }
}

void gameboardPrint(){
        cout << "Test" << endl;
}

int main(){
        const int COLUMN_SIZE = 6;
        int rowSize = 0;
        bool gameOver = false;
        Spaces gameBoard[rowSize][COLUMN_SIZE];

        StudentInfo();
        GameInfo();

        do{
                cout << "How many rows do you want on the board? (4-6 inclusively) " << endl;
                cin >> rowSize;

                if(rowSize > 6 ||  rowSize < 4){
                        cout << "Error: This value is out of range.\n" << endl;
                }
                else{}

        } while(rowSize > 6 || rowSize < 4);

        BoardInt(gameBoard, rowSize);

        while(gameOver = false){
                gameboardPrint();
                gameOver = true;
        }
        return 0;
}
Last edited on
closed account (E0p9LyTq)
Your game board is a C-style 2D array, you can't run-time resize it, the dimensions are set at compile time.

You can create a 2D vector array that can be dynamically created.
std::vector<std::vector<Spaces>> gameBoard(rowSize, std::vector<Spaces>(COUMN_SIZE));

You create it after you get your row size. You also need to rewrite your BoardInt() function to work with a 2D vector, passed as a reference. A templated function works well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <ios>
#include <iomanip>
#include <vector>

using namespace std;

enum Spaces
{
   BLANK = 1, RED, BLUE
}; //Spaces on the gameboard

void StudentInfo()
{ }

void GameInfo()
{
   cout << setfill('-') << setw(72) << "" << endl;
   cout << "Input game info" << endl;
   cout << setfill('-') << setw(72) << "" << endl;
}

template <typename T>
void BoardInt(std::vector<T>& gameBoarded)
{
   const size_t rowSize = gameBoarded.size();
   const size_t COLUMN_SIZE = gameBoarded[0].size();

   cout << "\nInitializing game board...\n" << endl;

   for (size_t i = 0; i < rowSize; ++i)
   {
      for (size_t j = 0; j < COLUMN_SIZE; ++j)
      {
         gameBoarded[i][j] = BLANK;
         cout << gameBoarded[i][j] << " ";
      }
      cout << endl;
   }
}

void gameboardPrint()
{
   cout << "Test" << endl;
}

int main()
{
   const int COLUMN_SIZE = 6;
   int rowSize = 0;
   bool gameOver = false;
   // Spaces gameBoard[rowSize][COLUMN_SIZE];

   StudentInfo();
   GameInfo();

   do
   {
      cout << "How many rows do you want on the board? (4-6 inclusively) " << endl;
      cin >> rowSize;

      if (rowSize > 6 || rowSize < 4)
      {
         cout << "Error: This value is out of range.\n" << endl;
      }
      else
      {
         break;
      }

   } while (rowSize > 6 || rowSize < 4);

   std::vector<std::vector<Spaces>> gameBoard(rowSize, std::vector<Spaces>(COLUMN_SIZE));
   BoardInt(gameBoard);

   while (gameOver = false)
   {
      gameboardPrint();
      gameOver = true;
   }
   return 0;
}

------------------------------------------------------------------------
Input game info
------------------------------------------------------------------------
How many rows do you want on the board? (4-6 inclusively)
5

Initializing game board...

1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
closed account (E0p9LyTq)
Why doesn't your gameBoardPrint() message print? You are assigning false to gameOver instead of checking for equality.

76
77
78
79
80
   while (gameOver == false)
   {
      gameboardPrint();
      gameOver = true;
   }
closed account (E0p9LyTq)
is there any way I can set each position to the enumerated type BLANK and then set it to character - instead of 1

Changing to a character enum is easy-peasy:
enum Spaces { BLANK = '-', RED = 'R', BLUE = 'B' };

Then change how you create the 2D vector:
std::vector<std::vector<char>> gameBoard(rowSize, std::vector<char>(COLUMN_SIZE));

Nothing else needs be changed in your code:
-----------------------------------------------------------------------
Input game info
-----------------------------------------------------------------------
How many rows do you want on the board? (4-6 inclusively): 4

Initializing game board...

- - - - - -
- - - - - -
- - - - - -
- - - - - -
Test


You want to change the 2nd row, 5th column to red? (remember arrays and vectors are zero-indexed):
gameBoard[1][4] = RED;

I've revamped the code to be more modular, still hacked-ish and crude:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <ios>
#include <iomanip>
#include <vector>

enum Spaces
{
   BLANK = '-', RED = 'R', BLUE = 'B'
};

void StudentInfo();

void GameInfo();

template <typename T>
void BoardInt(std::vector<T>&);

template <typename T>
void gameBoardPrint(std::vector<T>&);

int main()
{
   const int COLUMN_SIZE = 6;
   int rowSize = 0;
   bool gameOver = false;

   StudentInfo();
   GameInfo();

   do
   {
      std::cout << "How many rows do you want on the board? (4-6 inclusively): ";
      std::cin >> rowSize;

      if (rowSize > 6 || rowSize < 4)
      {
         std::cout << "Error: This value is out of range.\n\n";
      }
      else
      {
         break;
      }

   } while (rowSize > 6 || rowSize < 4);

   std::cout << "\nInitializing game board...\n";
   std::vector<std::vector<char>> gameBoard(rowSize, std::vector<char>(COLUMN_SIZE));
   BoardInt(gameBoard);

   gameBoardPrint(gameBoard);

   // change a position
   gameBoard[1][4] = RED;

   gameBoardPrint(gameBoard);
   gameOver = true;
}


void StudentInfo()
{ }

void GameInfo()
{
   std::cout << std::setfill('-') << std::setw(72) << '\n';
   std::cout << "Input game info\n";
   std::cout << std::setfill('-') << std::setw(72) << '\n';
}

template <typename T>
void BoardInt(std::vector<T>& gameBoard)
{
   const size_t rowSize = gameBoard.size();
   const size_t COLUMN_SIZE = gameBoard[0].size();

   for (size_t i = 0; i < rowSize; ++i)
   {
      for (size_t j = 0; j < COLUMN_SIZE; ++j)
      {
         gameBoard[i][j] = BLANK;
      }
   }
}

template <typename T>
void gameBoardPrint(std::vector<T>& gameBoard)
{
   const size_t rowSize = gameBoard.size();
   const size_t COLUMN_SIZE = gameBoard[0].size();

   std::cout << "\nPrinting game board...\n";
   for (size_t i = 0; i < rowSize; ++i)
   {
      for (size_t j = 0; j < COLUMN_SIZE; ++j)
      {
         std::cout << gameBoard[i][j] << " ";
      }
      std::cout << '\n';
   }
}

-----------------------------------------------------------------------
Input game info
-----------------------------------------------------------------------
How many rows do you want on the board? (4-6 inclusively): 4

Initializing game board...

Printing game board...
- - - - - -
- - - - - -
- - - - - -
- - - - - -

Printing game board...
- - - - - -
- - - - R -
- - - - - -
- - - - - -
How did you get the stack smashing error? I compiled it under g++ on cygwin and it just compiled with no errors or warnings and ran without any crashes. Input error detection even worked correctly for numbers out of range, although if I put some letters, the error message loops infinitely without allowing new input.
I'm running it on PuTTY
1
2
3
std::cout << "\nInitializing game board...\n";
std::vector<std::vector<char>> gameBoard(rowSize, std::vector<char>(COLUMN_SIZE));
BoardInt(gameBoard);

vs
1
2
std::cout << "\nInitializing game board...\n";
std::vector<std::vector<char>> gameBoard(rowSize, std::vector<char>(COLUMN_SIZE, BLANK));



Edit:
PuTTY is a SSH client. It provides SSH connection to remote machine. Remote machine has SSH server process, some OS, some shell, some compiler, etc. In other words, nothing "runs on PuTTY". I guess your "PC" has Windows and your remote does not.

@zaphraud: Do you use strict standard compliance with g++, or do you allow (the default) GNU extensions? The latter (IMHO unfortunately) supports VLAs.
Last edited on
closed account (E0p9LyTq)
@keskiverto,

I had forgotten about the additional parameter on vector construction that sets a value. Ooops.
I'm tempted to say that it was hiding in plain sight. In the
std::vector<std::vector<char>> gameBoard(foo, bar);
where
1
2
foo = rowSize
bar = std::vector<char>(COL...
@zaphraud: Do you use strict standard compliance with g++, or do you allow (the default) GNU extensions? The latter (IMHO unfortunately) supports VLAs.

I haven't turned anything off... so something the OP did is causing a segfault on their machine but it's running without errors or warnings on mine.
...

I added
1
2
3
//print something
        cout << "blah de blah";


right before the return 0; statement.

It only prints the blahs with an input value of 4. Otherwise, it silently quits.

If I print values from the array in the same spot, I see the segmentation fault - sometimes.

So yeah, something is still definitely wrong. It's just not giving me as many details about whats going wrong. I was just curious what conditions on what platform lead to a "stack smashing" error.
Last edited on
closed account (E0p9LyTq)
keskiverto wrote:
I'm tempted to say that it was hiding in plain sight.

Any code with std::vector has nothing to do with the OP's original code, they were trying to create a regular array of variable size at runtime.

I was simply narrowly focused on something, without looking at the bigger picture.
Last edited on
figured out my issue, I was declaring the array before prompting for the row size of the array, so the rowSize was 0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        int rowSize = 0;
        bool gameOver = false;
        Spaces gameBoard[rowSize][COLUMN_SIZE];

        StudentInfo();
        GameInfo();

        do{
                cout << "How many rows do you want on the board? (4-6 inclusively) " << endl;
                cin >> rowSize;

                if(rowSize > 6 ||  rowSize < 4){
                        cout << "Error: This value is out of range.\n" << endl;
                }
                else{}

        } while(rowSize > 6 || rowSize < 4);
How did you get the stack smashing error?

Compile with -fstack-protector-all. (At least.)

The stack smashing protector is a compiler-chosen random value that's pushed on the stack right after the return address. That value is checked right before the function returns, and if it has changed, the program has overrun (smashed) the stack.

This is a security feature - it helps prevent malicious users from exploiting buffer overruns.
Last edited on
Topic archived. No new replies allowed.