gpt4 book ai didi

c++ - std::list 中的 rbegin() 永远不等于指向列表的迭代器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:43:59 26 4
gpt4 key购买 nike

为什么下面的代码会崩溃?

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());

关于c++ - std::list 中的 rbegin() 永远不等于指向列表的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42984209/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com