2016-04-25 7 views
0

Es gibt einen Beispielcode, der den Fehler als Balg auftritt. Im Freigabemodus funktioniert und druckt fünf '-'. Im Debug-Modus funktioniert es jedoch nicht und tritt ein Laufzeitfehler auf, der 'Array-Iterator nicht dereferenzierbar' ist.Array Iterator nicht dereferencable Fehler

Umgebung Details: Windows 7 64bit Visual Studio 2015 Update 2

Ich weiß nicht, warum es Devotion zwischen Release und Debug-Modus. Vielen Dank im Voraus.

#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; 
} 

Antwort

3

Sie rufen *b wenn barr.end() ist. Dies verursacht undefined behaviour. Sie können * nur für einen Iterator verwenden, der auf ein Element des Arrays verweist.

+1

Beachten Sie, dass, obwohl es natürlich ist, dass es nicht definiert Verhalten in Bezug auf den Standard ist, das Verhalten tatsächlich in Bezug auf die spezifische Implementierung erklärt wird. Diese Erklärung ist, dass VC++ - Iteratoren im Debug-Modus solche Dinge überprüfen und Ausnahmen auslösen, wenn ein Iterator nicht korrekt verwendet wird. Und diese Prüfungen sind im Freigabemodus deaktiviert. –

+0

@BenjaminLindley Sie sind genau richtig. MSVC unterstützt den Debug-Iterator, um die Verwendung eines falschen Iterators zu erkennen. https://msdn.microsoft.com/en-us/library/aa985982.aspx – brown

-2

Überladen von Operatoren erfordert, dass mindestens ein Operand eine Klasse oder Aufzählungstyp ist. std::array<int, 5>::iterator ist nur ein typedef für int*, der ein eingebauter Typ ist. Sie müssen den Vergleichsoperator nicht überladen, da die Vergleiche zwischen den Zeigern bereits gut definiert sind.

Referenzen:

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

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

+0

Wenn dies der Fall wäre, dann wäre es ein Compilerfehler, kein Laufzeitfehler. –

+0

@BenjaminLindley Die Tatsache, dass es in VS2015 kompiliert, ist ein Fehler. Es kompiliert nicht in GCC und Clang. – user6249564

+0

Array-Iterator kann ein typedef für 'int *' sein oder nicht. In Fällen, in denen dies nicht der Fall ist, ist die Funktion in Ordnung. Es gibt keinen Compilerfehler hier –