简体   繁体   中英

C++ 2d “dynamic” array in a class?

So I am trying to learn about classes in C++ (I usually write Python) and I am getting some strange behavior from the following code which will be a dynamically sizing game of Tic Tac Toe:

#include <iostream>
#include <string>

// Square NxN board, win with N consecutive.
class TicTacToe {
public:
  void PrintBoard();
  void MakeMove(int p, int l);
  void checkMove(int &position);
  bool isWinner() const;
  void checkPlayer(int &number, char &move);
  TicTacToe(int s);

private:
  int player;
  int location;
  int size;
  int **board;
};

void TicTacToe::PrintBoard() {
  for (int i = 0; i < size; ++i) {
    for (int j = 0; j < size; ++j) {
      std::cout << board[i][j] << ' ';
    }
    std::cout << std::endl;
  }
}

TicTacToe::TicTacToe(int s) {
  size = s;
  board = new int * [size];
  if (board) {
    for(int i = 0; i < size; ++i) {
      board[i] = new int [size];
      assert(board[i]);
    }
  }
}

int main(int argc, char **argv) {
  TicTacToe game(3);
  TicTacToe Game(5);
  game.PrintBoard();
  Game.PrintBoard();
  return 0;
}

The code seems to be working properly, and properly allocating the size of the 2d arrays that represent the game boards. However, the values that are printing are a bit weird. I was hoping someone could explain why I am getting the following output:

0 536870912 0 
0 536870912 0 
0 536870912 0 
0 536870912 0 536870912 10 
0 536870912 0 536870912 8 
0 536870912 0 536870912 6 
0 536870912 0 536870912 4 
0 536870912 0 536870912 2 

My question mainly is why are the odd indexes of the array printing as '536870912' and not '0' and also why are there 10, 8, 6, 4, 2 in the final column of the second array? Am I doing something wrong? Is there a better way to allocate the board sizes? Any help is appreciated.

You haven't given any values to your board, so when you print out the values they are garbage. Try this which sets all the inital values to 0.

TicTacToe::TicTacToe(int s) {
  size = s;
  board = new int * [size];
  for(int i = 0; i < size; ++i) {
    board[i] = new int [size];
    for(int j = 0; j < size; ++j)
      board[i][j] = 0;
  }
}

Incidentally there's no need to check the return value of new , new never returns NULL, if it fails it throws an exception.

Welcome to StackOverflow. You're getting downvoted because you've encountered a (very) common issue, presented a wall of code and very little explanation, nor indication of what you already tried (or searched for on SO). That makes it harder for us to help.

To answer your first question, C++ is unlike Python in that raw memory allocated in this way is not (necessarily) initialized . To any value, let alone zero. Whatever value it had a second ago will remain unless you set it to something. Obviously, this is quite unpredictable--sometimes you just happen to get zeroed memory, sometimes it's completely random, and sometimes you encounter what you did. Regardless, it's rarely useful, so it's known as garbage.

To answer your second question, yes, we generally consider this wrong unless you're doing something pretty weird.

To your third question, std::vector is typically favored for this type of scenario.

With all that said, it seems like you are less interested in the final result and more in wrapping your head around things--great! I don't know what specific goals are or what your learning style is, but you might have an easier time starting in vanilla C, as it's simpler. C++ adds in a bunch of (admittedly useful) weirdness that tends to distract from the main educational value of learning C++, that is, getting your hands dirty with memory management. Just a thought.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM