这是对我之前的问题(Complexity of STL max_element)的跟进。
我想基本上从一组中弹出max元素,但我遇到了问题。
这大致是我的代码:
set<Object> objectSet;
Object pop_max_element() {
Object obj = *objectSet.rbegin();
set<Object>::iterator i = objectSet.end()--; //this seems terrible
objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
return obj;
}
早些时候我试过objectSet.erase(objectSet.rbegin());
,但编译器抱怨没有匹配的函数(我猜它不喜欢reverse_iterator)。我知道没有检查空集,但是当objectSet.size()&gt;&gt;时它失败了。 0
答案 0 :(得分:9)
你非常接近,但你试图在迭代器分配中做太多。您将后递减运算符应用于任何end
返回。我不确定那是什么,但几乎肯定不是你想要的。将end
的结果分配给i
,然后然后递减它以获取该集合的最后一个元素。
set<Object>::iterator i = objectSet.end();
--i;
Object obj = *i;
objectSet.erase(i);
return obj;
答案 1 :(得分:5)
你需要这样做:
set<Object> objectSet;
Object pop_max_element() {
Object obj = *objectSet.rbegin();
set<Object>::iterator i = --objectSet.end(); // NOTE: Predecrement; not postdecrement.
objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
return obj;
}
答案 2 :(得分:5)
声明
set<Object>::iterator i = objectSet.end()--;
表示'为...分配end()然后递减一个即将丢弃的临时变量'。换句话说,它与set<Object>::iterator i = objectSet.end();
相同,我相信你会认识到你无法擦除end(),因为它指向一个结尾。请改用这样的东西:
assert(!objectSet.empty()); // check there is something before end
set<Object>::iterator i = objectSet.end();
--i;
objectSet.erase(i);
并且没关系,这是一种合法的方式来为一个集合重现.back()
。
此外,反向迭代器有一个base()
成员转换为普通迭代器,我想你只能删除正常的迭代器 - 试试objectSet.erase(objectSet.rbegin().base())
。