1

I have these two almost identical bits of c++

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

with the output:

0x7ffd7b16998c

2

and

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

which produces the output:

0x7ffdb7ea105c

3

Why does the value of *(p+1) depend on what I output beforehand? If I delete the line

cout << &c << endl; 

completely i get the expected 1 as an output.

What on earth is happening?

Kuhlambo
  • 371
  • 3
  • 13

2 Answers2

2

What's happening is undefined behavior.

When you obtain a pointer to an int, you are allowed to use the value of that pointer alone; pointer arithmetic is meaningless.

In order for p+1 to produce an address that you can dereference, p must point to an array element other than its last element. In all other situations, reading *(p+1) is undefined.

Standards aside, the CPU must be taking that value from some place. You assume that the place must be the address of b, which is declared immediately after a. However, C++ makes no guarantees about location of local variables in memory relative to each other. It appears that the compiler reorders your variables, producing an output that you did not expect (and it's undefined anyway).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • It is undefined but reliably reproduces the same undefined behaviour, man that is horrible^^ if you are learning this stuff... as I am trying at the moment.. – Kuhlambo Feb 01 '17 at 11:14
  • @pindakaas I agree, the decision to leave some behavior undefined in a high-level programming language is quite horrible. A great deal of programs appear to be working fine on one standard-compliant platform, only to fail miserably when ported to a different standard-compliant platform. You can find bugs like this using [valgrind](http://valgrind.org/), but it is a very hard process. – Sergey Kalinichenko Feb 01 '17 at 11:19
1

*(p+1) accesses memory after a so it's Undefined Behaviour.

Propably you intended (*p)+1 to increase a by 1?

Yuriy Ivaskevych
  • 956
  • 8
  • 18
  • What do you mean by UB? Why would i need (*p)+1? this will always give the value of a+1 right? – Kuhlambo Feb 01 '17 at 11:11
  • @pindakaas I *suggested* `(*p)+1` because you haven't stated what *exactly* you want to happen. UB is happening because you access memory you shouldn't, because `*(p+1)` is adress of memory *after* `a` - it is similar to access array out of bounds. And when UB is happening *literally anything* can happen (there could be -371 in output for example) – Yuriy Ivaskevych Feb 01 '17 at 11:14
  • Okay. coming from python this stuff is hard to stomach. – Kuhlambo Feb 01 '17 at 11:16