【发布时间】:2012-03-21 20:17:30
【问题描述】:
我有一个国际象棋游戏,最初使用 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 对象的大小比被提升为的 Knight 或 Queen 大 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 来保留堆内存时,进入 new Pawn() 会导致它在 new 运算符中崩溃。无论如何,我认为这仍然与我对向量 stl 的工作原理缺乏完全了解有关。我知道它与我的 Pawn() 构造函数无关,因为它在游戏板初始化期间被调用了很多次。
【问题讨论】:
-
看起来像内存错误。如果您使用的是 Linux 或 OS X,我建议您使用 valgrind 来根除任何动态内存访问问题:valgrind.org
-
只有这两种方法正在运行?
-
请将您的程序缩减为显示错误的最短完整程序,并在您的问题中发布该完整、短程序。请参阅sscce.org 了解更多信息。
-
好的,抱歉,感谢您的链接。我将努力减少代码然后重现错误。这是个好建议,我可能会在我这样做之后解决它:)
标签: c++ pointers stl vector polymorphism