I am using std::equals defined in <algorithm> to check if two vectors are equal. It crashes when second vector is empty. I could avoid crash by checking if second vector is empty, but is there a reason to not include the check in equal function itself ?
Sample code:
std::vector<int> a;
for (int i = 0; i < 3; i) a.emplace_back(i);
std::vector<int> b;
for (int i = 0; i < 0; i) b.emplace_back(i);
std::equal(a.begin(), a.end(), b.begin());
CodePudding user response:
You call std::equal with 3 arguments, which in https://en.cppreference.com/w/cpp/algorithm/equal says:
Returns true if the range [first1, last1) is equal to the range [first2, first2 (last1 - first1)), and false otherwise
which will cause undefined behavior in you case
Use std::equal with 4 arguments instead:
std::equal(a.begin(), a.end(), b.begin(), b.end());
which will do:
Returns true if the range [first1, last1) is equal to the range [first2, last2), and false otherwise.
which is what you want.
Or, you can just use operator ==. std::vector overloads one:
a == b;
CodePudding user response:
The range (as the number of comparisons) of compared elements in this call
std::equal(a.begin(), a.end(), b.begin());
is specified by the first two arguments [a.begin(), a.end() ). But this range is invalid for the vector b.
Use this form of the algorithm
template<class InputIterator1, class InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2);
where ranges are specified separately for the both compared containers as
std::equal(a.begin(), a.end(), b.begin(), b.end());
