c ++和xcode - 调用对象函数抛出EXC_BAD_ACCESS

时间:2013-03-26 19:40:44

标签: c++ xcode

此代码在VS2010中运行正常,但现在我正在尝试使用xcode 4.6将其移植到我的Mac,并且它在运行时给我一些错误的访问错误。基本上我有一个包含2d瓷砖阵列的电路板类,当我创建电路板时,我可以访问瓷砖功能但是当我以后运行我的绘图功能时,它给了我糟糕的访问权限。以下是我的董事会成员的样本。

Board.h

#include "Tile.h"
class Board
{
private:
    //This is the GameBoard of a 2D array of Tiles
    Tile *** GameBoard;
    void CreateBoard(const int size);
void FillValues();
    ...
public:
Board(int size);
void DrawBoard();
    ...
}

Board.cpp

Board::Board(const int size)
{
won=false;
lost=false;
BoardSize =size;
GameBoard = new Tile**[size];
CreateBoard(size);
}

void Board::CreateBoard(const int size)
{
    ...
    FillValues()
}

void Board::FillValues()
{
    for(int x=1;x<BoardSize+1;x++)
    {
        for(int y =1;y<BoardSize+1;y++)
        {
            if (GameBoard[x][y]->Type()=="NumberTile")
            {
                                int neighbors = CountNeighbours(x,y);
                GameBoard[x][y]->SetValue(neighbors);
                                //This works
            }
        }
    }
}

void Board::DrawBoard()
{
for(int i=0;i<=BoardSize+1;i++)
{
    for (int j=0;j<=BoardSize+1;j++)
    {
        if (GameBoard[i][j]->Type() != "BorderTile") {
            GameBoard[i][j]->Draw();
            //This does not work, i get the error when it tries to use ->Type()
        }
    }
}
}

...

我称这样的函数为

GI = new Board(SCREEN_SIZE);
GI->DrawBoard();

1 个答案:

答案 0 :(得分:3)

GameBoard = new Tile**[size];

这只会创建一个Tile**数组。您还没有任何实际Tile甚至Tile*及更高版本,当您尝试使用GameBoard[x][y]->访问数组元素时,您将遇到未定义的行为。

如你所知,你需要这样做:

GameBoard = new Tile**[size];      // Allocate an array of Tile**
for (int i = 0; i < size; i++) {
  GameBoard[i] = new Tile*[size];  // Allocate an array of Tile*
  for (int j = 0; i < size; j++) {
     GameBoard[i][j] = new Tile(); // Allocate an array of Tile
  }
}

然而,这太糟糕了。这是三个动态分配,你必须记住在最后整理(并正确整理)。

更简单的方法是只有一个二维瓷砖阵列:

Tile GameBoard[CONSTEXPR_SIZE][CONSTEXPR_SIZE];

或者更好的是,使用std::array容器:

std::array<std::array<Tile, CONSTEXPR_SIZE>, CONSTEXPR_SIZE> GameBoard;

这里,给定的大小必须是常量表达式。如果您需要动态调整大小,请改用std::vector


在下面的评论中,您说数组的大小实际上是BoardSize+1。但是,您在外部和内部for循环中迭代了太多元素:

for(int i=0;i<=BoardSize+1;i++)

这应该是:

for(int i=0; i<BoardSize+1; i++)

同样在下面的评论中,您说Type会返回char*。这意味着你不能像这样进行字符串比较:

GameBoard[i][j]->Type() != "BorderTile"

这只是执行指针比较,因为左操作数是char*而右操作数可以转换为const char*。它比较字符串本身。相反,你想要:

GameBoard[i][j]->Type() != std::string("BorderTile")

这将强制使用std::string比较。