std::list 中的 rbegin() 永远不会等于指向列表的迭代器?
rbegin() in std::list is never equal to an iterator pointing into the list?
为什么下面的代码会崩溃?
int main(int argc, const char * argv[]) {
std::list<int> aList={1,2,3,4,5};
std::list<int>::reverse_iterator i=aList.rbegin();
i++;
i++;
assert(*i==3);//assertion passes as expected
while (i!=aList.rbegin()) { //never becomes false
aList.pop_back(); //segmentation fault
}
assert(*(aList.rbegin())==3);
return 0;
}
我假设 rbegin 最终会等于i并停止循环;然而没有发生。
注意我做了以下解决方法,仍然好奇上面的代码首先有什么问题
size_t differance =std::distance( aList.rbegin(),i);
while (differance >0) {
aList.pop_back();
differance--;
}
assert(*aList.rbegin()==3);
std::list::rbegin()
返回一个迭代器,该迭代器引用哨兵列表末尾节点,但取消引用存储在前一个节点中的值(在本例中为 5)。 此行为适用于std::list
的任何反向迭代器:反向迭代器在取消引用反向迭代器时从中获取值的节点是迭代器实际指向的节点之前的节点。
像这样可视化它,根据迭代器引用的元素:
rend() <-------- rbegin()
| |
1 2 3 4 5 (end)
| |
begin() --------> end()
这意味着取消引用值 3 的迭代器实际上是在内部引用值为 4 的元素。当值 4 从列表中删除时,存储在i
中的迭代器值将失效,此时您无法推理其行为。 它可能(并且应该)不等于所有其他迭代器。
您可以通过在*i == 3
时写出*(i.base())
的值来自己验证是否是这种情况。 你会看到*(i.base()) == 4
.
因此,您的问题不在于迭代器rbegin()
"永远不会等于指向列表的迭代器",而是您正在删除迭代器内部指向的元素,然后尝试将现在无效的迭代器与rbegin()
进行比较。
考虑使用aList.erase()
而不是循环。 由于您要从值为 4 的元素中删除数组的末尾,i.base()
已经为您提供了一个迭代器,您可以将其直接传递给aList.erase()
:
aList.erase(i.base(), aList.end());
看起来你已经全部颠倒了,递增反向迭代器会向后移动它。
并且pop_back()
将使最后一个元素的迭代器无效,因此循环中存在段错误。您应该做一个pop_front()
并检查(i !=rend())
相关文章:
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- C++未知长度字符串的数组,其行为类似于 Python 字符串列表
- C++ 列表等效于 C# 列表
- 类成员函数参数列表是否可以依赖于模板参数?
- 如何找出依赖于LIB文件的DLL列表?
- 条件_variable和unique_lock如何适用于线程安全列表
- G++ - 警告:扩展初始值设定项列表仅适用于 -std=C++11 或 -std=GNU++11
- 对函数参数的要求是否也适用于初始值设定项列表?
- 如何在 c++ 中将函数列表应用于字符串
- 如何将函数应用于可变参数列表并将它们猫到元组
- 如何获取应用于本地工作站的组策略对象列表
- 如何将函数应用于可变参数列表的每个组件并返回可变参数列表
- 在本地将 'using std::foo' 指令应用于构造函数初始值设定项列表 (C++)
- C 中的数组中的数组类似于Python中的内部列表
- search用字符串列表输入数字(类似于t9字典)
- 私有变量的读取晚于成员init列表
- C++中 Python 的列表[:x] 相当于什么?
- C++等效于字典/列表的Python代码
- 如何使用指针C++将类的析构函数转换为另一个类?类似于单向列表容器类和节点类
- c++(类似于python列表)