Is there a safe alternative to std::equal?

OldPeculier picture OldPeculier · May 1, 2013 · Viewed 7.4k times · Source

std::equal() is unsafe because the function cannot know whether it will overrun the length of the second container to be compared. That is:

std::vector< int > v( 100 );
std::vector< int > w( 10 );
bool same = std::equal( v.begin(), v.end(), w.begin() );

...will result in a buffer overrun for w.

Naturally we can test for these things (v.size() == w.size()), but compilers like Visual Studio 2010 still report the function itself as unsafe. And indeed it is unsafe in some fundamental sense: a team of programmers of varying levels of experience will eventually forget to compare sizes.

A safe alternative is easy to implement.

template< typename Iter1, typename Iter2 >
bool equal_safe( Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2 )
{
    while( begin1 != end1 && begin2 != end2 )
    {
        if( *begin1 != *begin2 )
        {
            return false;
        }
        ++begin1;
        ++begin2;
    }
    return begin1 == end1 && begin2 == end2;
}

But is there a safe alternative in the standard library?

Answer

Marshall Clow picture Marshall Clow · May 2, 2013

In C++14, the standard library will contain a version of std::equal that takes two pairs of iterators, similar to your safe_equal. Same for std::mismatch and std::is_permutation.