-7

following code:

int main(){

  int a;
  int b;
  int c=0;
  int *p;

  p=&a;
  *p = 10;
  *(p+1) = 20;
  *(p+2) = 30;

  cout << a << " " << b << " " << c << endl;
 
  return 0;
}

gives the output:

10 30 20

explanation ? if c is not initialized (int a,b,c;) results are expected: 10 20 30

sone13
  • 1
  • 1
  • 6
    This is undefined behaviour. The question "why" doesn't make any sense. – Evg Sep 06 '21 at 07:44
  • 3
    You have *undefined behavior!* You make `p` point to the *single* variable `a`. That means `p + 1` and `p + 2` will be *out of bounds*. – Some programmer dude Sep 06 '21 at 07:44
  • 1
    As for what really happens, there's no guarantee that your compiler will store variables in the order they are declared. Or even in increasing order. Or even that they are stored in some kind of "stack" even. – Some programmer dude Sep 06 '21 at 07:45
  • There should be a canonical dup for this question... – Ken Y-N Sep 06 '21 at 07:46
  • if random line of code cout << &b << endl; is added before return, results are correct. – sone13 Sep 06 '21 at 07:54
  • 5
    *if random line of code cout << &b << endl; is added before return, results are correct.* -- Undefined behavior is undefined. When I run your program in Visual C++, in debug mode, a runtime exception is thrown. So ask yourself -- is it worth your time in trying to play tricks with bad code, or actually spend the time to learn proper C++ programming? – PaulMcKenzie Sep 06 '21 at 07:55
  • As a matter of fact, Visual C++ refuses to compile your code due to `b` not being initialized. It was only after I initialized it to something was there a successful compilation. – PaulMcKenzie Sep 06 '21 at 08:07
  • @sone13 [Look at the output here](https://godbolt.org/z/b75qce494). This is what I am speaking of. So are you going to research into why the output shows up like that? If you want to do that, go ahead, but again, do you want to spend time on trying to figure out undefined behavior? If the answer is yes, you're on your own. – PaulMcKenzie Sep 06 '21 at 08:22
  • `results are expected: 10 20 30`. No. From the perspective of the language specification, `a` should have the value `10`, `c` should have the value `0` (since it has never been changed from the perspective of the language), and `b` should have an unspecified value (since it has never been initialized from the perspective of the language). `*(p+1) = 20; *(p+2) = 30;` are undefined behavior and could result in anything. From the perspective of the language there is no relation between `*(p+1)`/`*(p+2)` and the variables `b` and `c`. – t.niese Sep 06 '21 at 08:28

3 Answers3

3

That’s outright undefined behavior. Pointer arithmetic is only allowed inside single array (not even between struct members, although some compilers might tolerate the latter). The local variables don’t form an array. They may have arbitrary locations in memory.

numzero
  • 2,009
  • 6
  • 6
  • cout << &a << &b << &c .... shows successive addresses. – sone13 Sep 06 '21 at 08:02
  • 1
    @sone13 -- You're not understanding the point that is being made. Did you read the comments in the main section? – PaulMcKenzie Sep 06 '21 at 08:04
  • @sone13 It may show successive addresses today, and some random addresses tomorrow. Undefined is undefined, it might work as expected, or try to format your HDD, or do anything else. – numzero Sep 06 '21 at 08:11
  • cout &b and p+1 , results are identical – sone13 Sep 06 '21 at 08:11
  • @sone13 Please check [this page on cppreference](https://en.cppreference.com/w/cpp/language/ub) about undefined behavior. In short: No matter what you observe or think to observe, your program is buggy and anything might happen. It doesn't make any sense to reason about it or expect any specific output. – Lukas-T Sep 06 '21 at 08:27
  • @sone13 Do you understand that C++ is not assembler? It has its own rules, different from hardware rules. Because hardware don’t run C++. The compiler translates it first. It’s the compiler who needs to understand the code, it’s the compiler whose rules you have to obey to write C++. Obeying the standard is sufficient and usually the best way of that. – numzero Sep 06 '21 at 08:29
0

You've made an assumption that *(p+1) is b. There's no reason that will always be the case. How a compiler assigns memory addresses for variables is completely undefined, and will vary hugely based on many different factors (in your example, initialising a variable earlier changes it. The other big thing that would change it would be compiler optimizations). You really shouldn't be relying on relative memory locations.

Sam
  • 923
  • 5
  • 11
0

Pointer (p+1) doesn't point to integer variable b and pointer (p+2) doesn't point to variable c. So when you cout those variable you are getting vague values. Instead try using array because while initialising arrays compiler assign continuous memory for arrays. But when you declare variables continuous memory isn't assigned by compiler

Int a[3];
Int *p;
p = &a;
*p = 10;
*(p+1) = 20;
*(p+2) = 30;
cout<< a[0] <<a[1] <<a[2] ;
The Acturial Kid
  • 232
  • 1
  • 10
  • if cout &b and p+1 , results are identical – sone13 Sep 06 '21 at 08:06
  • 1
    @sone13 Again, there are no results when I attempt to compile your program, and even then, running your program crashes. I don't know what you are trying to accomplish by trying to get wrong code to "behave". – PaulMcKenzie Sep 06 '21 at 08:13
  • If variable "b" address and address in pointer p+1 are identical. Then *(p+1) cout the value in integer variable b. But then it's not necessary that pointer "p" will still be pointing at integer "a". – The Acturial Kid Sep 06 '21 at 08:15