I am trying to understand std::find(). Below is my code.
" 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.". But when I gave find(100) I am getting 7 rather than 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;
}
Output:
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
Thanks & Regards
Vishnu Beema
CodePudding user response:
The value 100 is not present in the set. So this call
auto a2 = s1.find(100);
returns the iterator s1.end()
. You may not dereference the iterator. This statement
cout << "find(100) : " << *a2 << endl;
invokes undefined behavior.
CodePudding user response:
The problem is that you're dereferencing an iterator a2
that points to s1.end()
leading to undefined behavior. This problem arose because you're not checking before dereferencing the iterators, if the element was found or not.
To solve this you should add an explicit check before dereferencing the iterators.
//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;
}
CodePudding user response:
auto a2 = s1.find(100); cout << "find(100) : " << *a2 << endl;
Here you dereference (*a2
) the end iterator. That is undefined behaviour - remember that s1.end()
points to one past the last element and must not be dereferenced.
You're unlucky that you got a value from that dereference - it would be more convenient if your program crashed or otherwise reported the problem. But UB doesn't have to be diagnosed in any way.
You might have spotted the problem if you had run your program using Valgrind's memory checker (or your preferred equivalent). But there's a good chance that's unable to detect it (if the set has over-allocated, which is likely).