C++ 迭代器引用不存在的值

C++ iterator reference non-exist value

提问人:Joelin Zou 提问时间:9/6/2023 更新时间:9/6/2023 访问量:40

问:

我想创建两个迭代器并不断指向多集(或列表)中的某些元素,但奇怪的是即使在多集/列表中也不返回一个值。在for循环遍历中,表现正常。p1p2*p1 *p2*it

#include <iostream>
#include <set>

using namespace std;

class MedianFinder
{

private:
    multiset<int> orderedNums;
    int size;
    multiset<int>::iterator p1, p2;

public:
    MedianFinder() : size(0)
    {
        p1 = p2 = orderedNums.begin();
    }

    void addNum(int num)
    {
        orderedNums.insert(num);
        size++;

        cout << "p1: " << *p1 << " p2: " << *p2 << endl;

        cout << "ordered: ";
        for (multiset<int>::iterator it = orderedNums.begin(); it != orderedNums.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
};

int main()
{
    MedianFinder medianFinder;
    medianFinder.addNum(5); 
    medianFinder.addNum(7); 
    medianFinder.addNum(9); 
    return 0;
}

控制台输出:

p1: 1 p2: 1
ordered: 5 
p1: 2 p2: 2
ordered: 5 7 
p1: 3 p2: 3
ordered: 5 7 9

list 和 multiset 的行为相同...

C++ 列表 迭代器 取消引用 多集

评论

0赞 Alan Birtles 9/6/2023
取消引用无效的迭代器或迭代器以具有未定义的行为,您期望发生什么?end()
0赞 Ada 9/6/2023
如果在插入第一个元素后在 addNum() 中初始化指针会发生什么?void addNum(int num) { orderedNums.insert(num); size++; p1 = p2 = orderedNums.begin(); ...
2赞 teapot418 9/6/2023
insert不会使迭代器无效,这很好。问题在于,在空多集上返回与 相同的东西。迭代器继续指向结束占位符并取消引用,即 UB。begin()end()p
0赞 Joelin Zou 9/8/2023
谢谢,所以输出是未定义的行为?总而言之,会在 之前插入元素,p1 和 p2 一直指向这些元素。这会导致在尊重 p1 和 p2 时出现未定义的行为。并重新分配以解决问题。1 2 3insertend()p1 = p2 = orderedNums.begin()addNums()

答:

-1赞 463035818_is_not_an_ai 9/6/2023 #1

这里

p1 = p2 = orderedNums.begin();

你使 和 等于 ,因为对于一个空容器。取消引用结束迭代器是未定义的。p1p2orderedNums.end()end == begin

std::multiset::insert不会使迭代器无效,但这不会改变 和 引用容器的事实。它们不会自动更新以引用新插入的元素。p1p2end

您的代码具有未定义的行为。

不确定代码的实际目的是什么。如果要将迭代器保留到插入的最后一个元素,则可以存储从 返回的迭代器。std::multiset::insert