如果在容器中找不到 set::find() 的值
value of set::find() if not found in container
我正在努力理解 std::find()
。下面是我的代码。
std::set::find
searches the container for an element equivalent to
val
and returns an iterator to it if found, otherwise it returns an
iterator to 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
auto a2 = s1.find(100);
cout << "find(100) : " << *a2 << endl;
在这里取消引用 (*a2
) 结束迭代器。这是未定义的行为 - 请记住 s1.end()
指向 最后一个元素 之后的一个,不能取消引用。
你很不幸你从那个取消引用中得到了一个值 - 如果你的程序崩溃或以其他方式报告问题会更方便。但 UB 不一定非要以任何方式诊断。
如果您 运行 您的程序使用 Valgrind 的内存检查器(或您喜欢的等效程序),您可能已经发现了问题。但是很有可能无法检测到它(如果集合有 over-allocated,这很可能)。
问题 是您取消引用指向 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;
}
集合中不存在值 100。所以这个调用
auto a2 = s1.find(100);
returns 迭代器 s1.end()
。您不能取消引用迭代器。此声明
cout << "find(100) : " << *a2 << endl;
调用未定义的行为。
我正在努力理解 std::find()
。下面是我的代码。
std::set::find
searches the container for an element equivalent toval
and returns an iterator to it if found, otherwise it returns an iterator toset::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
auto a2 = s1.find(100); cout << "find(100) : " << *a2 << endl;
在这里取消引用 (*a2
) 结束迭代器。这是未定义的行为 - 请记住 s1.end()
指向 最后一个元素 之后的一个,不能取消引用。
你很不幸你从那个取消引用中得到了一个值 - 如果你的程序崩溃或以其他方式报告问题会更方便。但 UB 不一定非要以任何方式诊断。
如果您 运行 您的程序使用 Valgrind 的内存检查器(或您喜欢的等效程序),您可能已经发现了问题。但是很有可能无法检测到它(如果集合有 over-allocated,这很可能)。
问题 是您取消引用指向 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;
}
集合中不存在值 100。所以这个调用
auto a2 = s1.find(100);
returns 迭代器 s1.end()
。您不能取消引用迭代器。此声明
cout << "find(100) : " << *a2 << endl;
调用未定义的行为。