1

このコードは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();
4

1 に答える 1

3
GameBoard = new Tile**[size];

これにより、の配列が作成されますTile**。まだ実際Tileのsまたはsがなく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
  }
}

しかし、これはひどいです。最後に片付ける(そして正しく片付ける)ために覚えておく必要があるのは、3つの動的割り当てです。

より簡単なアプローチは、タイルの2D配列を用意することです。

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"

左のオペランドはachar*で、右のオペランドはに変換可能であるため、これは単にポインタ比較を実行しますconst char*。文字列自体は比較されません。代わりに、次のようにします。

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

std::stringこれにより、比較が強制的に使用されます。

于 2013-03-26T19:44:01.047 に答える