【问题标题】:map/set iterator not derefrencable runtime error映射/设置迭代器不可取消引用运行时错误
【发布时间】:2012-08-30 07:33:08
【问题描述】:

我正在尝试运行这个函数:

os::TMXTileset* os::TMXMap::getTilesetFromGid(int gid)
    {
        TMXTileset* tileset;
        std::map<std::string, TMXTileset>::iterator it;
        std::map<std::string, TMXTileset>::iterator comp;

        for (it=tilesetMap.begin(); it != tilesetMap.end(); it++)
        {
            comp = it;
            comp++;
            if ((gid >= it->second.getFirstGid()) && (gid < comp->second.getFirstGid()))
            {
                return &it->second;
            }
        }
        tileset = &it->second;
        return tileset;
    }

..但它给了我这个错误:

"map/set iterator not derefrencable"

我的第一个想法是停止取消引用它(使用 it->second 而不是 (*it).second),但这并没有改变任何东西。

有什么想法吗?

【问题讨论】:

    标签: c++ stl map iterator


    【解决方案1】:

    您首先复制它,然后您推进该副本,然后您取消引用该副本。这意味着只要 end() 在最后一个元素之前的元素上,您就可以取消引用它。

    您可以轻松地在只有 1 个条目的地图上对此进行测试 - 它应该始终无法取消引用 comp。

    你应该这样做:

    TMXTileset* tileset;
    std::map<std::string, TMXTileset>::iterator it;
    std::map<std::string, TMXTileset>::iterator comp;
    
    for (it=tilesetMap.begin(); /*it != tilesetMap.end() can be ommited due to check for comp */; it++)
    {
        comp = it;
        comp++;
        if (comp == tilesetMap.end())
        {
           break;
        }
        ...
    }
    

    【讨论】:

    • 谢谢,太完美了。我认为 end() 指的是最后一个元素,这解释了我的错误。谢谢!
    • 考虑使用前置增量 (++i) 而不是后置增量。特别是在使用迭代器的情况下,这可能会更快。如果您不需要它,您还应该减少它的范围和补偿。新的 c++ 关键字 auto 对此非常有帮助。只需删除它的声明和 comp 并在它们的第一次使用前放置一个 auto 。 ( for (auto it=tilsetMap.begin() ... and auto comp = it; )
    【解决方案2】:

    如果没有中断,您的 for 循环将超出地图的末尾,因此您的倒数第三行将失败。

    【讨论】:

    • 当然可以。 for循环在it == tilesetMap.end()时停止,然后it->second没有定义。
    猜你喜欢
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    相关资源
    最近更新 更多