调试断言:矢量迭代器不相容(C ++)(Debug Assertion : Vector itera

2019-11-04 01:46发布

for (int i = 0; i < m_pGameField->dimensions()->first; i++)
    {
        for (int j = 0; j < m_pGameField->dimensions()->second; j++)
        {
            for (std::vector<std::shared_ptr<GameGridElement>>::iterator it = m_pGameField->getField(i, j)->getElements().begin();it != m_pGameField->getField(i, j)->getElements().end(); ++it)
            {
                if ((*it)->getName().compare("Spawn") == 0)
                {
                    tmpSpawns.push_back(std::static_pointer_cast<SpawnElement>((*it)));
                }
            }
        }
    }

嗨,我有一些问题上的代码。 代码段应该找到一个2D游戏领域的所有的产卵。 当涉及到第三的迭代的头它吐出以下消息“矢量迭代器不兼容调试断言错误现在,这是价值观的崩溃前一步我让他们形成Visual Studio调试器。:

的getElements()返回{大小= 0}; I = 0; J = 0; ()开始在空返回结构。 它是空结构

我看到向量是空的,但不应该由它!=()结尾部分处理?

Answer 1:

您还没有公布足够的代码是很确定,但以下的猜测应该是正确的:

getElements()的值最有可能的回报,而不是参考。

例如:

std::vector<std::shared_ptr<GameGridElement>> Field::getElements()
{
    // ...
    return result;
}

这将返回一个副本 ! 这意味着,每次通话时间getElements ,你会得到一个不同的载体。

对于编译器,这并没有什么差别。 类型安全不帮你,因为std::vector<std::shared_ptr<GameGridElement>>::iterator是一个std::vector<std::shared_ptr<GameGridElement>>::iterator即使你有两个迭代器属于不同的容器的实例 。 它们具有相同的类型,所以代码编译。

在运行时,但是,可以进行额外的检查,以确保正在真的比较两个迭代器属于同一个容器对象。 这原来看似随意的“怪异”的行为或虚假崩溃变成了一个明确保证崩溃立即告诉你的东西必须是固定的。

再次审议这一行:

for (
    std::vector<std::shared_ptr<GameGridElement>>::iterator
        it = m_pGameField->getField(i, j)->getElements().begin();
        it != m_pGameField->getField(i, j)->getElements().end();
    ++it
)

it被初始化为getElements().begin() ,然后通过比较!=getElements().end() 。 但是,如上所述,每个getElements()返回一个不同的载体,所以你得到不兼容的迭代器。

这里有一个简单的方法来解决这个问题:

std::vector<std::shared_ptr<GameGridElement>> elements =
    m_pGameField->getField(i, j)->getElements();

for (std::vector<std::shared_ptr<GameGridElement>>::iterator it = elements.begin();
    it != elements.end(); ++it)

这可以确保begin()end()返回迭代器相同的容器实例。


作为参考,这里是一段简单的代码来重现问题:

#include <vector>

int main()
{
    std::vector<int> v1;
    std::vector<int> v2;

    bool b = v1.begin() == v2.begin();
}

注意,C ++标准没有在运行时强制迭代器的兼容性检查。 你的编译器所提供的他们,你必须使用正确的编译器选项启用它们,或禁用它们,如果你不需要他们还是买不起。


顺便说一句,如果你可以使用C ++ 11,那么你可以使用一个基于范围for循环,不仅修正错误,而且使代码更大量简洁。



文章来源: Debug Assertion : Vector iterators incompatible (C++)