2016-07-22 15 views
4

Kann man unter Berücksichtigung des folgenden Codes Zeigerarithmetik auf nullptr ausführen?Die Nullptr- und Zeigerarithmetik

ich irgendwelche Offsets in einem anderen nullptr zu einem nullptr Ergebnisse übernehmen das Hinzufügen, bisher MSVC Ergebnisse produzieren, wie ich erwartet hatte, aber ich bin etwas unsicher darüber, ob mit nullptr wie das ist sicher:

float * x = nullptr; 

float * y = x + 31; // I assume y is a nullptr after this assigment 

if (y != nullptr) 
{ 
    /* do something */ 
} 

Antwort

10

Sie didn Definiere nicht, was "sicher" für dich bedeutet, aber unabhängig davon hat der von dir vorgeschlagene Code undefiniertes Verhalten. Die Zeigerarithmetik ist nur für Zeigerwerte zulässig, die auf ein Array-Objekt zeigen, oder möglicherweise auf ein Ende des Arrays. (Nicht-Array-Objekte werden für die Zwecke dieser Regel als Array mit einem Element betrachtet.)

Da der Null-Zeiger niemals die Adresse eines Objekts oder eines Objekts ist, kann Ihr Code niemals wohldefiniertes Verhalten aufweisen .

+0

'int * a; a ++; 'ist UB, auch wenn ich den Zeiger nicht dereferenziere? Kannst du eine Referenz dafür geben? – user463035818

+4

@ tobi303: Es gibt keine Referenz dafür, da der Standard nicht explizit angeben muss, dass er undefiniert ist. [expr.add]/5 definiert das Verhalten von pointer + integer * nur für Zeiger auf Arrays (oder pointer-to-object, das als ein Array von 1 fungiert). Wenn der Zeiger nicht auf ein Array zeigt, ist das Verhalten definitionsgemäß undefiniert (außer im Fall des Hinzufügens von 0, das [expr.add]/8 für alle Zeiger definiert). –

+3

@ tobi303 UB bedeutet nicht "crash", es bedeutet "wir haben nicht definiert was das tut". Während dies geschieht, können Compiler aggressiv UB optimieren und erkennen und Ihr Programm sich extrem unerwartet verhalten. Eine Schule der Optimierung ist, "da UB nicht in einem wohlgeformten Programm auftreten kann, kann jede Logikkette, die zu UB führt, sicher als eine Möglichkeit eliminiert werden, bis hin zu expliziten' if'-Überprüfungen in Ihrem Code. " Kurz gesagt, UB kann zu * time travel * Bugs führen, bei denen sich Code, der weit von der UB entfernt ist, in einer Weise verhält, die nicht mit dem Code übereinstimmt, den Sie geschrieben haben. – Yakk

1

Nein, das Hinzufügen eines Offsets zu einem Nullptr führt nicht zu einem Nullptr. Dies ist ein nicht definiertes Verhalten.

+2

Sie haben Recht, dass das Hinzufügen eines Nicht-Null-Offsets nicht zu einem Nullptr führt. Das Hinzufügen/Subtrahieren von Null zu/von einem Nullzeiger ist jedoch gut definiert und führt zu einem Nullzeiger (dies ist ein spezifischer Unterschied zwischen C und C++ - in C ist dies undefiniert). – Peter

1

... ist es sicher, Zeigerarithmetik auf nullptr zu tun?

Nein, Arithmetik auf der nullptr ist nicht gut definiert, da sie selbst Typ kein Zeiger ist (aber Conversions existieren Werte aller Zeigertypen auf NULL).

See here;

std::nullptr_t ist der Typ des Nullzeigerliterals nullptr. Es ist ein eindeutiger Typ, der nicht selbst ein Zeigertyp oder ein Zeiger auf den Elementtyp ist.


Im Allgemeinen beliebige Zeigerarithmetik (auch auf dem Wert NULL) wird mit ziemlicher Sicherheit zu Problemen führen - Sie, dass der Speicher nicht zugewiesen haben - es ist nicht deins ist zu versuchen, zu lesen oder zu schreiben.

Zu Vergleichszwecken (z. B. eine nach dem Ende), wird es Ihnen gut gehen, aber ansonsten führt der Code, den Sie haben, zu undefiniertem Verhalten.

Weitere Informationen finden Sie in Wikipedia unter undefined behavior.

+0

Ich bin mir nicht sicher über die Logik in Ihrem zweiten Absatz: Zeigerarithmetik verursacht nicht Lesen von oder Schreiben in den Speicher. Speicher hat nichts mit dem OP-Problem zu tun. –

+0

Das war mehr über das willkürliche Teilproblem für das OP. Ich werde das aufräumen. – Niall

2
is it safe to do pointer arithmetic on nullptr? 

C++ definiert zwei Arten von Operationen auf nullptr. Für:

float * x=nullptr; 
float * y=nullptr; 
  1. x +/- 0 = x

  2. x-y=0 //note x and y have the same type

Sie können nicht eine Annahme über das, was nicht definiert ist, so dass Sie es nicht tun sollte.

+1

Tatsächlich gibt es noch eine dritte Operation: 'x == y'. Scheint trivial, aber es bedeutet wirklich, dass es nur einen Nullzeigerwert gibt. – MSalters

Verwandte Themen