【发布时间】:2020-02-02 11:59:50
【问题描述】:
我正在尝试测试“find”在 std:map 中是否安全,所以我在使用“find”测试后删除了一个元素,但该元素的迭代器仍然有效。即使我再次使用 find ,它也会再次找到擦除的元素。
根据文档:
引用被函数删除的元素的迭代器、指针和引用无效。 所有其他迭代器、指针和引用保持其有效性。
为什么第二个迭代器
auto it_2 = numeros.find("uno");如果元素被擦除了还能找到它?为什么
std::cout << it->first << " : " << it->second << std::endl;在“擦除”后打印元素?这意味着从地图中删除元素时 find 是安全的?
这是我的例子。
#include <iostream>
#include <map>
int main(int argc, char *argv[])
{
std::map<std::string,unsigned int> numeros = { {"uno",1}, {"dos",2}, {"tres",3}};
auto it = numeros.find("uno");
std::cout << it->first << " : " << it->second << std::endl;
std::cout << std::endl;
numeros.erase("uno");
std::cout << it->first << " : " << it->second << std::endl;
std::cout << std::endl;
auto it_2 = numeros.find("uno");
std::cout << it_2->first << " : " << it_2->second << std::endl;
std::cout << std::endl;
for (auto i=numeros.begin(); i!=numeros.end(); ++i)
std::cout << i->first << " : " << i->second << std::endl;
return 0;
}
输出
uno : 1
uno : 1
uno : 1
dos : 2
tres : 3
谢谢!
【问题讨论】:
-
erase使所有当前映射迭代器无效,如果在此之后取消引用一个,则调用未定义的行为。it_2也将是一个结束迭代器,再次取消引用它将调用 ub 但您可以在取消引用之前对其进行测试以查看它是否为numeros.end()。 -
在我的编译器中
it_2不打印uno : 1,它崩溃了。您应该在使用前检查它。 -
在
erase指向它的元素后取消引用it获得正确的结果并不能保证您正在观察定义的行为。确实,正如@George 指出的那样,您正在观察未定义的行为。 -
@masoud 我使用 clang++ Apple clang 版本 11.0.0 它打印这个输出,但是正如 walnut 所说,我的程序有未定义的行为,在其他编译器下它可以做任何事情。
标签: c++