为什么可以打印' e'它被删除后?
set <int> s;
for (auto &e : s){
s.erase(e);
cout << e;
}
同样发生在这里,
list <int> l;
l.push_back(1);
l.push_back(2);
auto it = l.begin();
为什么会这样?
l.erase(it++);
cout << *it;
这不是吗?
l.erase(it);
it++;
cout << *it;
答案 0 :(得分:4)
在这两种情况下,您都有未定义的行为。在第一个e
中是对已被破坏的对象的引用(悬空引用)。对该引用的任何访问都是未定义的行为。它可能会崩溃,打印随机数或格式化您的硬盘。在这种情况下,打印出您最初想到的数字。
在列表的情况下,有效的案例表现如下:
auto it2 = it;
it++;
l.erase(it2);
cout << *it;
在第二种情况下,您可以:
l.erase(it);
// it is no longer valid at this point. You cannot use it.
it++; // Undefined behaviour.
cout << *it; // Anything can happen
答案 1 :(得分:2)
没有&#34;工作&#34;。
只有似乎可以正常工作。
你的程序实际上有一个致命的错误。
编译器在一般情况下不会为您检测到此错误(因为它们无法解决),因此您的代码仍会编译。在一般情况下,C ++运行时不会为您检查内存边界(因为您不会为您不使用的内容付费,这将是一个昂贵的强迫我们使用功能)所以你的代码仍在运行。
但是你写了一个无效的程序。
答案 2 :(得分:0)
对于列表,当你传递参数时,迭代器在赋值给擦除函数后已经递增,因此迭代器仍然有效并指向集合中的下一个元素。
在第二种情况下,迭代器无效,因为它在增量之前已被擦除。