У меня есть игра в шахматы, в которой изначально использовался список stl для хранения шахматных фигур, которые я переключил на вектор для лучшей производительности.Я понимаю, что векторы не поддерживают полиморфизм, поэтому, чтобы обойти это, я сохраняю вектор <Unit *>
вместо <Unit>
.Все мои объекты шахматных фигур (пешка, ладья, слон и т. Д.) Наследуются от класса юнитов.
Однако, похоже, проблема с вектором и повреждением кучи все еще существует.Я думаю, что отследил это до следующей функции:
Unit *ChessGame::PromoteUnit(Unit *_oldUnit, UnitType _newType)
{
vector<Unit *> &army = (_oldUnit->m_gameColor == WHITE) ? m_whiteArmy : m_blackArmy;
Unit *newUnit = NULL;
for (unsigned int i = 0; i < army.size(); ++i)
{
if (army[i]->m_subId == _oldUnit->m_subId)
{
if (_newType == QUEEN && _oldUnit->m_gameColor == WHITE)
{
newUnit = new Queen(*_oldUnit);
newUnit->ActiveTexture_(m_textureMan->TextureId_(WhiteQueen));
}
else if (_newType == KNIGHT && _oldUnit->m_gameColor == WHITE)
{
newUnit = new Knight(*_oldUnit);
newUnit->ActiveTexture_(m_textureMan->TextureId_(WhiteKnight));
}
else if (_newType == QUEEN && _oldUnit->m_gameColor == BLACK)
{
newUnit = new Queen(*_oldUnit);
newUnit->ActiveTexture_(m_textureMan->TextureId_(BlackQueen));
}
else if (_newType == KNIGHT && _oldUnit->m_gameColor == BLACK)
{
newUnit = new Knight(*_oldUnit);
newUnit->ActiveTexture_(m_textureMan->TextureId_(BlackKnight));
}
newUnit->m_wasPawn = true;
delete army[i];
army[i] = newUnit;
break;
}
}
m_selectedUnit = newUnit;
return newUnit;
}
Поскольку указатель составляет всего 4 байта, независимо от того, на что он указывает, есть причина, по которой вектор stl все еще будет иметь проблему втакой случай?Мой объект Pawn размером на 8 байт больше, чем продвигаемый Рыцарь или Королева, и, возможно, объяснит странные ошибки памяти, которые я получаю.Когда я делаю резервную копию своей истории ходов и нажимаю на свою функцию понижения, чтобы отменить продвижение:
Unit *ChessGame::DemoteUnit(Unit *_oldUnit, UnitType _newType)
{
COUT("ChessGameManager::_DemoteUnit(Unit *, UnitType)");
vector<Unit *> &army = (_oldUnit->m_gameColor == WHITE) ? m_whiteArmy : m_blackArmy;
Unit *newUnit = NULL;
for (unsigned int i = 0; i < army.size(); ++i)
{
if (army[i]->m_subId == _oldUnit->m_subId)
{
newUnit = new Pawn();
newUnit->m_wasPawn = false;
if (_oldUnit->m_gameColor == WHITE)
newUnit->ActiveTexture_(m_textureMan->TextureId_(WhitePawn));
newUnit->m_gameColor = _oldUnit->m_gameColor;
newUnit->MobilityValid_(false);
newUnit->Color_(RvColor::ClrWhite);
newUnit->m_square = _oldUnit->m_square;
newUnit->m_captured = false;
newUnit->m_origin = _oldUnit->m_origin;
newUnit->m_subId = _oldUnit->m_subId;
newUnit->m_visible = true;
//newUnit->m_square->m_unit = newUnit;
delete army[i];
army[i] = newUnit;
break;
}
}
return newUnit;
}
Он буквально падает на:
newUnit = new Pawn();
Переход в новую пешку () заставляетпадение внутри нового оператора, когда он пытается использовать malloc для резервирования памяти кучи.В любом случае, я думаю, что это все-таки связано с отсутствием у меня полного понимания того, как работает вектор stl.Я знаю, что это не имеет ничего общего с моим конструктором Pawn (), так как он вызывался много раз во время инициализации игрового поля.