0

Here is the code of my tutorial

#include<iostream>
using namespace std;

int main()
{
    int arr[5] = {8,2,9,4,5},a,b,*ptr;
    int c = 5;

    ptr = arr;
    a = *ptr + 10;
    ptr = &c;   
    ptr += 2;
    cout<<*(ptr+1);
}

I'm a little confused why the output is 9. When ptr is pointing to c, which is valued 5, how can the pointer be incremented +2 since c is not an array?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Anonymous
  • 29
  • 7
  • 3
    Yikes! There is only one `c`. When you set `ptr = &c;`, the `ptr` points to (holds the address of) `c`. Doing `ptr += 2;` puts you 2 integers (8-bytes) after `c`. (that is *undefined behavior* -- that's not part of `c` -- no pun intended, well maybe...) – David C. Rankin Mar 10 '20 at 05:37
  • 1
    Where did you get this code from? – JohnFilleau Mar 10 '20 at 05:42
  • Here is a pointer basics post that may help [Can I dereference the address of an integer pointer?](https://stackoverflow.com/questions/57451436/can-i-dereference-the-address-of-an-integer-pointer/57451658?r=SearchResults&s=2|42.6216#57451658) – David C. Rankin Mar 10 '20 at 05:43

4 Answers4

2

Undefined behavior

Let's break it down:

int arr[5] = {8,2,9,4,5},a,b,*ptr;
int c = 5;

ptr = arr;      // ptr = address of arr[0]
a = *ptr + 10;  // a = (arr[0] + 10) = (8 + 10) = 18
ptr = &c;       // ptr = address of c
ptr += 2;       // UNDEFINED BEHAVIOR, c is not an array
cout<<*(ptr+1); // COULD PRINT ANYTHING

Not that we've established undefined behavior, the language lawyers can't sue me to explain what might be happening:

The variables of main are possibly piled onto the stack as follows. It's convenient that the elements on the stack are integer for this simple example:

0x100 c 
0x104 arr[0]
0x108 arr[1]
0x10C arr[2]
0x110 arr[3]
0x114 arr[4]
0x118 a
0x11C b
0x120 ptr // address of the variable ptr, not what ptr points to

Hence, ptr+2 is the same address as the arr[1] in the array, which holds a value of "2". And then then the additional (ptr+1) expression is the address of arr[2], which holds the value 9.

But that's because you are getting lucky. Any other system or compiler could crash the program or make the lights dim in your house. Such is the nature of undefined behavior.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • 1
    `ptr += 2` is not undefined behavior. It's only undefined once you dereference. – JohnFilleau Mar 10 '20 at 05:52
  • Language lawyers. I can never escape them. – selbie Mar 10 '20 at 05:53
  • 1
    It's the only taste of control I have in this chaotic world :( – JohnFilleau Mar 10 '20 at 05:54
  • 1
    @John I believe the behavior of `ptr += 2` is undefined, though `ptr += 1` would be OK. See 8.7 [expr.add] paragraph 4. The "(possibly-hypothetical) element" wording refers only to a single element past the end of the array. (`c` is treated as a 1-element array.) – Keith Thompson Mar 10 '20 at 06:23
  • @Keith that's such a hairy sentence. I think you're right. Footnote 86) in that was key to me being able to parse it. – JohnFilleau Mar 10 '20 at 06:36
  • A quibble: "*UNDEFINED BEHAVIOR, c is not an array*" - No, `c` is not an array, but `c` is treated as a 1-element array for purposes of pointer arithmetic. The problem is that the array object that `c` is equivalent to is not big enough. `p+1` is a valid one-past-the-end pointer (dereferencing it would have UB), but `p+2` by itself has UB. – Keith Thompson Mar 10 '20 at 06:56
  • @KeithThompson incrementing a pointer beyond the 1-past-end is not UB, as long as the pointer is not dereferenced. That same pointer is allowed to be decremented to bring it back into valid range. That would not be possible if the increment were UB to begin with. – Remy Lebeau Mar 10 '20 at 08:21
  • @RemyLebeau Yes, it is UB, and no, that's not possible. C++17 8.7 [expr.add] paragraph 4:"When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression `P` points to element `x[i]` of an array object `x` with `n` elements, the expressions `P + J` and `J + P` (where `J` has the value `j`) point to the (possibly-hypothetical) element `x[i + j]` `if 0 ≤ i + j ≤ n;` otherwise, the behavior is undefined." – Keith Thompson Mar 10 '20 at 15:50
0

I think you are missing the * in ptr

#include<iostream>
using namespace std;


int main()
{
    int arr[5] = {8,2,9,4,5},a,b,*ptr;
    int c = 5;

    ptr = arr;
    a = *ptr + 10;
    ptr = &c;
    (*ptr) += 2;
    cout<<*(ptr+1);
}

It will print 8, But your program undefined behavior due to this line

  ptr += 2; 
srilakshmikanthanp
  • 2,231
  • 1
  • 8
  • 25
0

Well, the pointer is not pointing to c.

when you did ptr += 2; the pointer got incremented from c and is now pointing to a memory space having a garbage value.

When I ran the code I got 612602545 as output which clearly is a garbage value. The output you get will differ each time you run the code or from system to system.

0

Output of your program is not deterministic. ptr pointing to c has been incremented by 2. As ptr was not pointing to contiguous memory structure (Like array), it is not possible to determine what ptr is pointing at after increment. As it is int pointer, every increment will cause it to jump by sizeof(int). Derefrencing ptr after increment will try to read next sizeof(int) bytes as int. So you can get any garbage value.

nkvns
  • 580
  • 3
  • 5