2017-02-01 3 views
1

Ich habe diese beiden nahezu identischen Bits von C++Zeiger Aritmetic ändert sich abhängig von der Ausgabe?

#include <iostream> 
using namespace std; 
int main(){ 
    int a = 0; 
    int b = 1; 
    int c = 2; 
    int d = 3; 
    int *p = &a; 
    cout << &c << endl; 
    cout << *(p+1); 
} 

mit dem Ausgang:

0x7ffd7b16998c

und

#include <iostream> 
using namespace std; 

int main(){ 
    int a = 0; 
    int b = 1; 
    int c = 2; 
    int d = 3; 
    int *p = &a; 
    cout << &d << endl; 
    cout << *(p+1); 
} 

die die Ausgabe erzeugt:

0x7ffdb7ea105c

Warum der Wert von * ist (p + 1) davon abhängen, welche I-Ausgang vorher? Wenn ich die Linie

cout << &c << endl; 

vollständig löschen i die erwartete 1 als Ausgang erhalten.

Was auf der Erde geschieht?

+2

Beide rufen * undefiniertes Verhalten * auf, so dass Sie nichts (oder alles) erwarten können. – UnholySheep

+0

Okay, ich habe nur damit herumgespielt. Es erzeugt dieses Verhalten zuverlässig, weshalb ich überrascht war. – pindakaas

+0

danke für den Link @usr – pindakaas

Antwort

2

Was geschieht ist undefiniertes Verhalten.

Wenn Sie einen Zeiger auf ein int erhalten, werden Sie den Wert dieses Zeigers allein zu verwenden, erlaubt; Zeigerarithmetik ist bedeutungslos.

Damit p+1 eine Adresse erzeugt, die Sie dereferenzieren können, muss p auf ein Array-Element zeigen, das nicht das letzte Element ist. In allen anderen Situationen ist das Lesen von *(p+1) nicht definiert.

Standards beiseite, die CPU muss diesen Wert von einige Platz nehmen. Sie gehen davon aus, dass der Ort die Adresse b sein muss, die nach a sofort erklärt. C++ gibt jedoch keine Garantien über die relative Position der lokalen Variablen im Speicher. Es sieht so aus, als ob der Compiler Ihre Variablen neu anordnet und eine Ausgabe erzeugt, die Sie nicht erwartet haben (und die sowieso nicht definiert ist).

+0

Es ist unbestimmt, reproduziert aber zuverlässig das gleiche undefinierte Verhalten, Mann, der schrecklich ist ^^ wenn Sie dieses Zeug lernen ... wie ich es gerade versuche .. – pindakaas

+0

@pindakaas Ich stimme zu, die Entscheidung, etwas Verhalten undefiniert zu lassen eine High-Level-Programmiersprache ist ziemlich schrecklich. Eine große Anzahl von Programmen scheint auf einer standardkonformen Plattform gut zu funktionieren, nur um bei der Portierung auf eine andere standardkonforme Plattform kläglich zu versagen. Sie können Fehler wie diese mit [Valgrind] (http://valgrind.org/) finden, aber es ist ein sehr harter Prozess. – dasblinkenlight

1

*(p+1) greift auf den Speicher nacha so ist es undefinierten Verhalten.

Vermutlich beabsichtigten Sie (*p)+1, um a von 1 zu erhöhen?

+0

Was Sie von UB bedeuten sie? Warum sollte ich (* p) +1 brauchen? das wird immer den Wert von a + 1 geben, richtig? – pindakaas

+0

@pindakaas I * vorgeschlagen * '(* p) + 1 ', weil Sie haben nicht gesagt, was * genau * Sie passieren sollen. UB passiert, weil Sie auf Speicher zugreifen, den Sie nicht sollten, weil '* (p + 1)' Adresse von Speicher * nach * 'a 'ist - es ist ähnlich wie Zugriffsmatrix außerhalb der Grenzen. Und wenn UB passiert * kann buchstäblich alles * passieren (es könnte -371 in der Ausgabe zum Beispiel sein) –

+0

Okay. Von Python kommend ist dieses Zeug schwer zu ertragen. – pindakaas

Verwandte Themen