0

There is a sample code that occurs the error as bellows. In release mode, it works and prints five '-'. However, in debug mode, it doesn't work and occurs a runtime error that is 'array iterator not dereferencable'.

environment details : Windows 7 64bit Visual Studio 2015 update 2

I don't know why there are deferences between release and debug mode. Thanks in advance.

#include <iostream>
#include <array>

static bool operator != (int * a, std::array<int, 5>::iterator &b)
{
    return a != &(*b);
}

int main(void)
{
    std::array<int, 5> arr = { 0,0,0,0,0 };

    for (auto* it = &arr[0]; it != arr.end(); it++)
    {
        std::cout << "-" << std::endl;
    }

    return 0;
}
brown
  • 3
  • 1

2 Answers2

3

You call *b when b is arr.end(). This causes undefined behaviour. You can only use * on an iterator that refers to an element of the array.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • 1
    Note that while it is true of course that it is undefined behavior with respect to the standard, the behavior is in fact easily explained with respect to the specific implementation. That explanation being that VC++ iterators have checks for things like this in debug mode, and throw exceptions when an iterator is improperly used. And those checks are disabled in release mode. – Benjamin Lindley Apr 25 '16 at 04:40
  • @BenjaminLindley You're exactly right. MSVC supports debug iterator to detect incorrect iterator use. https://msdn.microsoft.com/en-us/library/aa985982.aspx – brown May 16 '16 at 03:19
-2

Overloading operators requires that at least one operand be a class or enumeration type. std::array<int, 5>::iterator is just a typedef for int*, which is a built-in type. You don't need to overload the comparison operator since the comparisons between pointers are already well-defined.

References:

https://isocpp.org/wiki/faq/intrinsic-types#intrinsics-and-operator-overloading

https://gcc.gnu.org/onlinedocs/libstdc++/manual/iterators.html