如果在容器中找不到set::find()的值



我正在努力理解std::find()。下面是我的代码。

std::set::find在容器中搜索与val,如果找到则返回迭代器,否则返回迭代器到set::end

但当我给find(100)时,我得到的是7,而不是20。

#include <iostream>
#include <set>
using namespace std;
int main()
{
set <int> s1{20, 7, 2};
s1.insert(10);
s1.insert(5);
s1.insert(15);
s1.insert(1);

cout << "size()     : " << s1.size() << endl;
cout << "max_size() : " << s1.max_size() << endl;
cout << "empty()    : " << s1.empty() << endl;

for(auto itr = s1.begin(); itr != s1.end(); itr++)
cout << *itr << " ";
cout << endl;

cout << endl << "---- find(value) ----" << endl;
auto a1 = s1.find(10);
//cout << "find(10)  : " << a1 << " " << *a1 << endl;
cout << "find(10)  : " << *a1 << endl;
auto a2 = s1.find(100);
cout << "find(100) : " << *a2 << endl;

cout << endl << "---- count(value) ----" << endl;
cout << "s1.count(10) : " << s1.count(10) << endl;
cout << "s1.count(100) : " << s1.count(100) << endl;

return 0;
}

输出

size()     : 7
max_size() : 107374182
empty()    : 0
1 2 5 7 10 15 20
---- find(value) ----
find(10)  : 10
find(100) : 7

---- count(value) ----
s1.count(10) : 1
s1.count(100) : 0

问题是您正在取消引用指向s1.end()的迭代器a2,从而导致未定义的行为。出现这个问题是因为在取消引用迭代器之前没有检查元素是否被找到。

若要解决问题,您应该在取消引用迭代器之前添加一个显式检查。

//dereference only if the element was found
if(a2!=s1.end())
{
std::cout << "find(100) : " << *a2 << std::endl; 
}
//otherwise print a message saying element not found 
else 
{
std::cout<<"element not found"<<std::endl;
}
auto a2 = s1.find(100);
cout << "find(100) : " << *a2 << endl;

此处取消引用(*a2)结束迭代器。这是未定义的行为-请记住,s1.end()指向最后一个元素之后的,并且不能取消引用。

不幸的是,你从取消引用中得到了一个值——如果你的程序崩溃或以其他方式报告了问题,那会更方便。但是UB不需要以任何方式进行诊断。

如果你使用Valgrind的内存检查器(或你喜欢的同等工具)运行程序,你可能已经发现了这个问题。但很有可能无法检测到它(如果集合分配过多,很可能)。

集合中不存在值100。所以这个调用

auto a2 = s1.find(100);

返回迭代器CCD_ 10。您不能取消引用迭代器。此声明

cout << "find(100) : " << *a2 << endl;

调用未定义的行为。

最新更新