C ++ - 向量迭代器+偏移超出范围
Posted
技术标签:
【中文标题】C ++ - 向量迭代器+偏移超出范围【英文标题】:C++ - Vector iterator + offset out of range 【发布时间】:2013-11-02 23:31:01 【问题描述】:我已经查看了大约 10 个关于同一消息的答案,但还没有找到我的问题。
在 Level 类的 level.h 中:
std::vector<Bomb> m_bombs;
在 level.cpp 中:
添加炸弹:
Bomb bomb;
bomb.owner = player;
bomb.power = power;
bomb.x = pos.x;
bomb.y = pos.y;
bomb.timer = 3.0f;
m_bombs.push_back(bomb);
检查炸弹(每一帧):
void Level::updateBombs(float dt)
for(int i = 0; i < m_bombs.size(); i++)
m_bombs[i].timer -= dt;
if(m_bombs[i].timer <= 0)
m_bombs.erase(m_bombs.begin() + i);
我 100% 确定程序会在调用擦除函数的那一行崩溃。我能够从向量中输出信息,这使得这种方式更加混乱。炸弹在向量中是正确的。如果我执行 m_bombs.remove_last() 它会删除向量中的最后一个元素。似乎只是擦除和开始()有问题。
【问题讨论】:
两个 cmets:(1) 如果您erase()
索引处的元素 i
,则需要再次检查索引 i
,因为旧索引 i+1
已移动到 i
. (2) 不建议在游戏中使用可变时间步长,因为它会导致难以重现的意外行为。
【参考方案1】:
您可以使用erase-remove-idiom 修复您的代码。
m_bombs.erase(std::remove_if(m_bombs.begin(), m_bombs.end(),
[](const Bomb& b) return b.timer < 0.0f;),
m_bombs.end());
最好将updateBombs
函数拆分为两个函数:
updateBombs() does bomb timer update only
removeBombs() removes bombs which expired
【讨论】:
【参考方案2】:也许您可以尝试向后擦除矢量,例如如果要擦除炸弹索引 3 和 5,则删除索引为 5 和 3 的炸弹,因为如果您从0
到N-1
按顺序擦除,当您擦除索引 3 时,索引 5 将变为索引4,这可能导致到达循环的最后一步时越界。
试试这个:
int pivot = 0
void Level::updateBombs(float dt)
for(int i = 0; i < m_bombs.size(); i++)
m_bombs[i].timer -= dt;
if(m_bombs[i].timer <= 0)
m_bombs.erase(m_bombs.begin() + i - pivot);
pivot++;
【讨论】:
【参考方案3】:我在清除或创建矢量时遇到了类似的问题。 出现问题是因为在运行时使用了 2 个不同版本的 dll。调用 Open CV 函数时发生了清除和创建,这些函数似乎使用与我的 Visual Studio 不同的运行时库。 更改视觉工作室终于解决了这个问题(我在更改视觉工作室之前尝试了很多旧的 OpenCV 构建,但无济于事)。 VS 2008 和 2013 不起作用,VS2010 起作用。
【讨论】:
【参考方案4】:我会将m_bombs.size()
替换为您自己的int
变量,您在移除炸弹后会减少该变量。我个人遇到过.size()
的问题。它应该返回向量中的元素数,但我有一个空向量,.size()
返回大于零的数字。也许尝试这样做有助于缩小您的问题范围。
【讨论】:
以上是关于C ++ - 向量迭代器+偏移超出范围的主要内容,如果未能解决你的问题,请参考以下文章