我有一个国际象棋游戏,最初使用stl列表来存储我转换为矢量以获得更好性能的棋子。我知道向量不支持多态,所以为了解决这个问题,我存储的是<Unit *>
而不是<Unit>
的向量。我的所有棋子对象(Pawn,Rook,Bishop等)都继承自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来保留堆内存时,单步执行新的Pawn()会导致它在new运算符内崩溃。无论如何我认为它仍然与我对矢量stl如何工作缺乏完全理解有关。我知道它与我的Pawn()构造函数无关,因为它在游戏板初始化期间被多次调用。
答案 0 :(得分:0)
我怀疑,但无法从您分享的信息中证明,ChessGame
的复制构造函数和复制赋值运算符执行m_whiteArmy
和m_blackArmy
的浅层副本。 (注意:如果您没有提供复制构造函数或复制赋值运算符,编译器会为您提供它们。编译器提供的那些运算符可以执行浅复制。)
您违反了Rule of Three。
您可以通过以下方式解决此问题:
ChessGame
对象。= delete
。std::shared_ptr
)。或