对set迭代器解引用会导致seg错误

Dereferencing a set iterator causes a seg fault

本文关键字:seg 错误 引用 set 迭代器      更新时间:2023-10-16

我试图确定为什么下面的代码在第10行(我们解引用upgradeIter)上抛出段错误。

bool UpgradeType::isAffected(const UnitType *unitType) const{
    if(std::find(effects.begin(), effects.end(), unitType)!=effects.end()) return true;
    // Check if the unit has any of the affected tags
    std::set<string>::iterator upgradeIter;
    for(upgradeIter = tags.begin(); upgradeIter != tags.end(); ++upgradeIter) {
        std::set<string>::iterator unitIter;
        for(unitIter = unitType->getTags().begin(); unitIter != unitType->getTags().end(); ++unitIter) {
            string unitTag = *unitIter;
            string upgradeTag = *upgradeIter;
            if(unitTag == upgradeTag) return true;
        }
    }
    return false;
}

上下文是UpgradeType有"标签"(只是一组字符串)。单位也有标签。如果一个单元与升级共享至少一个标签,则该单元受到升级的影响。

我看不出上面提到的行为什么会崩溃。在我看来,在任何情况下迭代器都不可能是无效的。

在显示tags内容的代码的其他部分(以非常相似的方式使用),输出与预期一致。

编辑:我刚刚发现unitType->getTags().size()是0。所以我不明白为什么要执行for循环的主体。然而,unitIter != unitType->getTags().end()的值为true。

我在这个网站的Yggdrasil的帮助下找到了一个解决方案(这也意味着Matt McNabb在问题的评论是正确的)。下面引用他的帖子:

正如有人或多或少提到的stackoverflow:更改getTags()以返回引用,而不是值/副本。

const set &getTags() const {return tags;}

注意返回类型是const,所以使用const迭代器。

不确定这是不是全部,但你肯定不希望在那里(深)复制。迭代器越界是因为你检查了另一个集合的末尾。每次调用getTags()都会得到它自己的副本。