C++ C++;为什么这些代码有效?
为什么删除后可以打印“e”C++ C++;为什么这些代码有效?,c++,pointers,stl,C++,Pointers,Stl,为什么删除后可以打印“e” set <int> s; for (auto &e : s){ s.erase(e); cout << e; } set; 用于(自动和电气:s){ s、 删除(e); cout在这两种情况下,您都有未定义的行为。在第一种情况下,e是对已销毁对象的引用(悬挂引用)。对该引用的任何访问都是未定义的行为。它可能会崩溃、打印随机数或格式化硬盘。在本例中,它似乎打印了您第一次想到的数字 在列表的情况下,有效的情况表现为: au
set <int> s;
for (auto &e : s){
s.erase(e);
cout << e;
}
set;
用于(自动和电气:s){
s、 删除(e);
cout在这两种情况下,您都有未定义的行为。在第一种情况下,e
是对已销毁对象的引用(悬挂引用)。对该引用的任何访问都是未定义的行为。它可能会崩溃、打印随机数或格式化硬盘。在本例中,它似乎打印了您第一次想到的数字
在列表的情况下,有效的情况表现为:
auto it2 = it;
it++;
l.erase(it2);
cout << *it;
auto it2=it;
it++;
l、 擦除(it2);
它不能“工作”。
它似乎只起作用,纯属偶然
你的程序实际上有一个致命的错误
编译器在一般情况下不会检测到这个bug(因为它们不能),所以你的代码仍然编译。C++运行库不为一般情况下做内存边界检查(因为你不为你不使用的东西付费,这将是一个昂贵的特性,所以你的代码仍然运行)。
但是您编写了一个无效的程序。在列表的情况下,当您传递参数it++时,迭代器已在赋值后递增以擦除函数,因此迭代器仍然有效,并指向集合中的下一个元素
在第二种情况下,迭代器无效,因为它在递增之前已被擦除。未定义的行为。基于范围的循环也有与最后一种情况相同的错误(因为基于范围的循环是根据递增迭代器的循环定义的)。
l.erase(it++);
cout << *it;
l.erase(it);
it++;
cout << *it;
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