C++ 存在类析构函数释放二维数组的问题

标签 c++

第一次发海报,yadayada。在做家庭作业时,我在让析构函数正常工作时遇到了问题。程序会编译成功,但是运行时会抛出:

*** glibc detected *** ./bmain: munmap_chunk(): invalid pointer: (random memory address)

我确定这是由我的析构函数引起的,因为当我将其注释掉时,一切正常。我已经使用过析构函数,它当前的形式是我认为应该是正确的,但显然不是。有人可以指出我做错了什么吗?如果我发布了太多代码,我提前表示歉意,但我宁愿提供过多的信息,也不愿提供不足的信息。

gameBoard.h

#include <iostream>
#include <iomanip>
#include <string>

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;
};

gameBoardImp.cpp

#include "gameBoard.h"

gameBoard::gameBoard(int x, int y)
{
    if (x < ROW_MIN || x > ROW_MAX)
    {
       cout << "Error.  Invalid game board size.  Number of rows must be between " << ROW_MIN << " and " << ROW_MAX << "." << endl;
       cout << "Board not created." << endl;
    }
    else if (y < COL_MIN || y > COL_MAX)
    {
       cout << "Error.  Invalid game board size.  Number of columns must be between " << COL_MIN << " and " << COL_MAX << "." << endl;
       cout << "Board not created." << endl;
    }
    else
    {
       rows = x;
       cols = y;
       board = new char* [rows];
          for (int row = 0; row < rows; row++)
          {
             board[row] = new char[cols];
             for (int col = 0; col < cols; col++)
             {
                board[row][col] = '?';
             }
          }
    }
}

gameBoard::~gameBoard()
{
   if (board != NULL)
   {
      for (int i = 0; i < rows; i++)
      {
         delete [] board[i];
      }
      delete []board;
      board = NULL;
   }
}

void gameBoard::setCell(int x, int y, char piece)
{
   if (x > rows || x < 0)
   {
      cout << "Error.  Invalid board location.  X has to be between 0 and " << (rows - 1) << " ." << endl;
   }

   else if (y > cols || y < 0)
   {
      cout << "Error.  Invalid board location.  Y has to be between 0 and " << (cols - 1) << " ." << endl;
   }

   else board[x][y] = piece;
}

char gameBoard::getCell(int x, int y) const
{
   if (x > rows || x < 0)
   {
      cout << "Error.  Invalid board location.  X has to be between 0 and " << (rows - 1) << " ." << endl;
   }

   if (y > cols || y < 0)
   {
      cout << "Error.  Invalid board location.  Y has to be between 0 and " << (cols - 1) << " ." << endl;
   }

   return board[x][y];
}

void gameBoard::printBoard()
{
   cout << " " << setw(cols) << setfill('-') << "-" << " " << endl;
   for (int i = 0; i < rows; i++)
   {
      cout << "|";
      for (int j = 0; j < cols; j++)
      {
         cout << board[i][j];
      }
      cout << "|" << endl;
   }
   cout << " " << setw(cols) << setfill('-') << "-" << " " << endl;
}

bmain.cpp

// CS 202 Provided Main


#include <iostream>
#include <iomanip>
#include <string>

#include "gameBoard.h"

using namespace std;

int main()
{
// ---------------------------------------
//  Some valid declarations

    gameBoard brd1(10, 10);
    gameBoard brd2(8, 8);

// ---------------------------------------
//  Some invalid declarations

    cout << endl << "*** Invalid declarations -> should show errors." << endl;
    cout << endl;
    gameBoard brd3(1, 1);           // error
    gameBoard brd4(9, 60);          // error

// ---------------------------------------
//  Try board #1

    cout << endl;
    cout << "*** Board #1 *******************************" << endl;
    cout << endl;

    {
        brd1.printBoard();

        for (int i=0; i<10; i++)
            brd1.setCell(i,i,'x');

        cout << endl;
        cout << "Cell (0,1) is :" << brd1.getCell(0,1) << endl;
        cout << "Cell (1,1) is :" << brd1.getCell(1,1) << endl;
        cout << "Cell (1,0) is :" << brd1.getCell(1,0) << endl << 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 << endl;
    cout << "*** Board #2 -> Error Testing *************" << endl;
    cout << 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 << endl;

    cout << endl;
    cout << "*** Board #2 *******************************" << endl;
    cout << endl;


    for (int i=0; i<8; i++)
        brd2.setCell(i,i,'x');

    for (int i=0, j=7; i<8; i++, j--)
        brd2.setCell(i,j,'y');

    brd2.printBoard();

    cout << endl;
    cout << "********************************************" << endl;
    cout << endl;

    return 0;
}

最佳答案

在构造函数中,当xy无效时,您不会将board设置为NULL,因此它未初始化。这会导致析构函数删除[]无效指针。

关于C++ 存在类析构函数释放二维数组的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12683317/

相关文章:

c++ - 完美转发和 std::forward<T> 的使用

c++ - 调试和发布版本之间可能出现的差异?

c++ getline没有得到输入

c++ - 编译器错误 : 1 unresolved external

c++ - 字符串不能开始参数声明

c++ - 如何改进我的类(class)的运算符重载?

c++ - 如何确保 SqLite 中的只读事务?

c++ - 在基于策略的类中保留构造的隐性

c++为什么级联共享对象链接

c++ - VS.NET C++ 2010 中智能感知和编译器的区别