C++ 取消对集合迭代器的引用会导致seg错误
我试图确定为什么下面的代码在第10行抛出segfault(在那里我们取消了对升级程序的引用)C++ 取消对集合迭代器的引用会导致seg错误,c++,segmentation-fault,C++,Segmentation Fault,我试图确定为什么下面的代码在第10行抛出segfault(在那里我们取消了对升级程序的引用) bool UpgradeType::isAffected(const UnitType*UnitType)const{ 如果(std::find(effects.begin()、effects.end()、unitType)!=effects.end())返回true; //检查装置是否有任何受影响的标签 std::set::迭代器升级器; 对于(upgradeIter=tags.begin();upg
bool UpgradeType::isAffected(const UnitType*UnitType)const{
如果(std::find(effects.begin()、effects.end()、unitType)!=effects.end())返回true;
//检查装置是否有任何受影响的标签
std::set::迭代器升级器;
对于(upgradeIter=tags.begin();upgradeIter!=tags.end();++upgradeIter){
std::set::iterator unitIter;
对于(unitIter=unitType->getTags().begin();unitIter!=unitType->getTags().end();++unitIter){
字符串unitTag=*unitIter;
字符串upgradeTag=*upgradeIter;
if(unitTag==upgradeTag)返回true;
}
}
返回false;
}
上下文是UpgradeType
有“标记”(只是一组字符串)。单位也有标签。如果某个单元与升级共享至少一个标签,则该单元将受到升级的影响
我看不出有任何理由说明这条线路会崩溃。在我看来,迭代器在任何情况下都是无效的
在显示标记内容的代码的其他部分中(以非常类似的方式使用),输出与预期一样
编辑:我刚刚发现unitType->getTags().size()
是0。所以我不明白为什么for循环的主体会被执行<代码>unitIter!=但是,unitType->getTags().end()
的计算结果为true。这似乎是错的。我在Yggdrasil的帮助下找到了解决办法(这也意味着马特·麦克纳布在问题中的评论是正确的)。以下引用他的帖子:
正如有人在stackoverflow上或多或少提到的:更改getTags()以返回引用,而不是值/副本
const set&getTags()const{return tags;}
请注意,返回类型是const,因此请使用const迭代器
不确定是否就这些,但你肯定不想要(深度)拷贝。迭代器越界,因为您检查了另一个集合的结尾。对getTags()的每个调用都有自己的副本
可能有无数的原因,不一定与集合及其迭代器本身有关。可能您的字符串已与整个
标记一起销毁。请尝试插入诊断输出,或查看调试器中的变量。@n.m.,但标记
是升级类型
实例的字段,在游戏结束之前不会被销毁。据我所知,向量的成员不会被销毁,直到向量被销毁。事实是程序崩溃了。这意味着你对其行为的一些猜测是无效的。通过独立检查验证所有内容。您的类中有正确的复制构造函数和复制赋值运算符吗?getTags()
的返回类型是什么?如果它按值返回一个容器,那么该循环将出现可怕的错误。
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;
}