title: C++ having issue with class destructor deallocating a 2d array
body: <p>First time poster, yadayada.  Working on a homework assignment and I'm having an issue getting a destructor to work quite properly.  The program will compile successfully, but when it runs, it throws:</p>
  
  <pre><code>*** glibc detected *** ./bmain: munmap_chunk(): invalid pointer: (random memory address)
  </code></pre>
  
  <p>I've determined that this is being caused by my destructor, since when I comment it out everything works fine.  I've played with the destructor, and its current form is what I <strong>think</strong> should be correct, but obviously isn't.  Can someone point out to me what I'm doing wrong?  I apologize in advance if I've posted too much code, but I'd rather provide information overload instead of not enough.</p>
  
  <p>gameBoard.h</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;iomanip&gt;
  #include &lt;string&gt;
  
  const int ROW_MIN = 3;
  const int ROW_MAX = 50;
  const int COL_MIN = 3;
  const int COL_MAX = 50;
  
  using namespace std;
  
  class gameBoard
  {
      public:
  
         gameBoard(int x = ROW_MIN, int y = COL_MIN);
  
         ~gameBoard();
  
         void setCell(int x = 0, int y = 0, char piece = '?');
  
         char getCell(int x = 0, int y = 0) const;
  
         void printBoard();
  
     protected:
  
        int rows;
        int cols;
        char **board;
  };
  </code></pre>
  
  <p>gameBoardImp.cpp</p>
  
  <pre><code>#include "gameBoard.h"
  
  gameBoard::gameBoard(int x, int y)
  {
      if (x &lt; ROW_MIN || x &gt; ROW_MAX)
      {
         cout &lt;&lt; "Error.  Invalid game board size.  Number of rows must be between " &lt;&lt; ROW_MIN &lt;&lt; " and " &lt;&lt; ROW_MAX &lt;&lt; "." &lt;&lt; endl;
         cout &lt;&lt; "Board not created." &lt;&lt; endl;
      }
      else if (y &lt; COL_MIN || y &gt; COL_MAX)
      {
         cout &lt;&lt; "Error.  Invalid game board size.  Number of columns must be between " &lt;&lt; COL_MIN &lt;&lt; " and " &lt;&lt; COL_MAX &lt;&lt; "." &lt;&lt; endl;
         cout &lt;&lt; "Board not created." &lt;&lt; endl;
      }
      else
      {
         rows = x;
         cols = y;
         board = new char* [rows];
            for (int row = 0; row &lt; rows; row++)
            {
               board[row] = new char[cols];
               for (int col = 0; col &lt; cols; col++)
               {
                  board[row][col] = '?';
               }
            }
      }
  }
  
  gameBoard::~gameBoard()
  {
     if (board != NULL)
     {
        for (int i = 0; i &lt; rows; i++)
        {
           delete [] board[i];
        }
        delete []board;
        board = NULL;
     }
  }
  
  void gameBoard::setCell(int x, int y, char piece)
  {
     if (x &gt; rows || x &lt; 0)
     {
        cout &lt;&lt; "Error.  Invalid board location.  X has to be between 0 and " &lt;&lt; (rows - 1) &lt;&lt; " ." &lt;&lt; endl;
     }
  
     else if (y &gt; cols || y &lt; 0)
     {
        cout &lt;&lt; "Error.  Invalid board location.  Y has to be between 0 and " &lt;&lt; (cols - 1) &lt;&lt; " ." &lt;&lt; endl;
     }
  
     else board[x][y] = piece;
  }
  
  char gameBoard::getCell(int x, int y) const
  {
     if (x &gt; rows || x &lt; 0)
     {
        cout &lt;&lt; "Error.  Invalid board location.  X has to be between 0 and " &lt;&lt; (rows - 1) &lt;&lt; " ." &lt;&lt; endl;
     }
  
     if (y &gt; cols || y &lt; 0)
     {
        cout &lt;&lt; "Error.  Invalid board location.  Y has to be between 0 and " &lt;&lt; (cols - 1) &lt;&lt; " ." &lt;&lt; endl;
     }
  
     return board[x][y];
  }
  
  void gameBoard::printBoard()
  {
     cout &lt;&lt; " " &lt;&lt; setw(cols) &lt;&lt; setfill('-') &lt;&lt; "-" &lt;&lt; " " &lt;&lt; endl;
     for (int i = 0; i &lt; rows; i++)
     {
        cout &lt;&lt; "|";
        for (int j = 0; j &lt; cols; j++)
        {
           cout &lt;&lt; board[i][j];
        }
        cout &lt;&lt; "|" &lt;&lt; endl;
     }
     cout &lt;&lt; " " &lt;&lt; setw(cols) &lt;&lt; setfill('-') &lt;&lt; "-" &lt;&lt; " " &lt;&lt; endl;
  }
  </code></pre>
  
  <p>bmain.cpp</p>
  
  <pre><code>// CS 202 Provided Main
  
  
  #include &lt;iostream&gt;
  #include &lt;iomanip&gt;
  #include &lt;string&gt;
  
  #include "gameBoard.h"
  
  using namespace std;
  
  int main()
  {
  // ---------------------------------------
  //  Some valid declarations
  
      gameBoard brd1(10, 10);
      gameBoard brd2(8, 8);
  
  // ---------------------------------------
  //  Some invalid declarations
  
      cout &lt;&lt; endl &lt;&lt; "*** Invalid declarations -&gt; should show errors." &lt;&lt; endl;
      cout &lt;&lt; endl;
      gameBoard brd3(1, 1);           // error
      gameBoard brd4(9, 60);          // error
  
  // ---------------------------------------
  //  Try board #1
  
      cout &lt;&lt; endl;
      cout &lt;&lt; "*** Board #1 *******************************" &lt;&lt; endl;
      cout &lt;&lt; endl;
  
      {
          brd1.printBoard();
  
          for (int i=0; i&lt;10; i++)
              brd1.setCell(i,i,'x');
  
          cout &lt;&lt; endl;
          cout &lt;&lt; "Cell (0,1) is :" &lt;&lt; brd1.getCell(0,1) &lt;&lt; endl;
          cout &lt;&lt; "Cell (1,1) is :" &lt;&lt; brd1.getCell(1,1) &lt;&lt; endl;
          cout &lt;&lt; "Cell (1,0) is :" &lt;&lt; brd1.getCell(1,0) &lt;&lt; endl &lt;&lt; endl;
  
          brd1.printBoard();
      }
  // Note, brd1 goes out of scope here...
  
  //  uncommenting this print board will crash if the destructor works correctly.
  //  brd1.~gameBoard();
  
  // ---------------------------------------
  //  Try board #2
  
      cout &lt;&lt; endl;
      cout &lt;&lt; "*** Board #2 -&gt; Error Testing *************" &lt;&lt; endl;
      cout &lt;&lt; endl;
      brd2.setCell(10,10,'x');        // error
      brd2.setCell(1,10,'x');         // error
      brd2.setCell(10,1,'x');         // error
      brd2.setCell(5,-1,'x');         // error
      brd2.setCell(-5,1,'x');         // error
      cout &lt;&lt; endl;
  
      cout &lt;&lt; endl;
      cout &lt;&lt; "*** Board #2 *******************************" &lt;&lt; endl;
      cout &lt;&lt; endl;
  
  
      for (int i=0; i&lt;8; i++)
          brd2.setCell(i,i,'x');
  
      for (int i=0, j=7; i&lt;8; i++, j--)
          brd2.setCell(i,j,'y');
  
      brd2.printBoard();
  
      cout &lt;&lt; endl;
      cout &lt;&lt; "********************************************" &lt;&lt; endl;
      cout &lt;&lt; endl;
  
      return 0;
  }
  </code></pre>