Доступ к частному массиву указателей на объекты из метода в переполнении стека

Я действительно не уверен, что искать, чтобы попытаться найти мой ответ, поэтому, пожалуйста, перенаправьте меня к любым соответствующим статьям, и я заранее извиняюсь.

Я действительно новичок в C ++ и пытаюсь сделать игру 3×3 CLI Tile. Я могу назначить объекты Tile частному массиву указателей в конструкторе TileGame и убедиться, что у них есть действительные адреса памяти (или я так думаю). Моя проблема заключается в том, что я запускаю метод, чтобы попытаться получить доступ к этим данным. Похоже, что первый элемент в массиве имеет значение, но остальные выглядят очень странно. Я уверен, что это что-то маленькое, но я в растерянности относительно того, что я делаю неправильно. Я также пытался создать метод доступа, но это только усложняло ситуацию.

#include <iostream>
using namespace std;

class Tile
{
private:
int position;
int tileID;
public:
Tile(int, int);
};

// tile constructor
Tile::Tile(int p, int id) : position(p), tileID(id) {}

class TileGame
{
private:
const int MAX_TILES;
Tile* tiles[];
public:
TileGame();
void shuffle();
};

// game constructor
TileGame::TileGame() : MAX_TILES(8)
{
Tile* tiles[MAX_TILES];
for (int i = 0; i < MAX_TILES; i++)
{
tiles[i] = new tile(i, i);
}

// spit out the addresses for each
cout << endl << "From TileGame(): " << endl;
for (int i = 0; i < MAX_TILES; i++)
{
cout << tiles[i] << endl;
}
}

void TileGame::shuffle()
{
// spit out the addresses for each
cout << endl << "From TileGame(): " << endl;
for (int i = 0; i < MAX_TILES; i++)
{
cout << tiles[i] << endl; // <-- This seems to be the problem
}
}

int main()
{
TileGame* game = new TileGame();
game->shuffle();
}

Это должно скомпилировать (мне пришлось перепечатать его, так что я надеюсь, что не допустил ошибок.) Вывод, который я получаю, выглядит примерно так:

From TileGame():
0x7f9349c03aa0
0x7f9349c03ab0
0x7f9349c03ac0
0x7f9349c03ad0
0x7f9349c03ae0
0x7f9349c03af0
0x7f9349c03b00
0x7f9349c03b10

From shuffle():
0x7fff9502752c
0x100
0
0
0
0
0
0

Я пришел к этому моменту, когда продолжал получать ошибки сегмента, пытаясь получить доступ tiles[] ценности. Мысли?

0

Решение

tiles массив, который создается в конструкторе TileGame это не tiles массив в Game объект. Избавьтесь от одного в конструкторе.

Также тоже могут указатели. tiles массив может содержать Tile объекты; нет необходимости для косвенного news. Точно так же нет необходимости game быть указателем. Просто создайте его как TileGame объект.

1

Другие решения

Ваш конструктор ничего не делает для инициализации члена с именем tiles; вместо этого он заполняет локальный массив с тем же именем. Это отбрасывается, утечка выделенной памяти, когда конструктор выходит. Затем вы получаете неопределенное поведение (в вашем случае, ошибка сегментации), когда вы пытаетесь использовать неинициализированный член.

Член должен быть указателем, а не массивом, если вы не знаете размер во время компиляции:

Tile ** tiles;

выделяется как:

tiles = new Tile* [MAX_TILES];

Не забудьте удалить каждую плитку (delete tiles[i]) и сам массив (delete [] tiles) в деструкторе; и, как всегда, когда сами управляете ресурсами, помните Правило трех.

Еще лучше, используйте std::vector так что вам не нужно управлять памятью самостоятельно. В общем, вы должны избегать динамического выделения, когда оно вам не нужно; например, TileGame вы создаете в main может быть автоматической переменной (TileGame game;) исправить утечку памяти у вас там.

4

По вопросам рекламы [email protected]