# Weird pointer outcome

1. Oct 20, 2014

### Zondrina

1. The problem statement, all variables and given/known data

Not homework, but I don't really know where else to put this.

Below is some code and it's relevant output, but the output is what I'm concerned about.

2. Relevant equations

3. The attempt at a solution

Code (Text):

#include <stdio.h>
#include <stdlib.h>

void foo(int a, int b) {
int r = a+b;
a += 2;
printf("(AR1) r = %d, a = %d \n", r, a);
}

void foo2(int *a, int *b){
*a = (*a)*2;
b = a;
printf("(AR2) *a = %d, *b = %d \n", *a, *b);
}

int main() {
int x = 5, y = 2;
int *p = &x, *r = &y;
printf("(AR3) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);

foo(x,y);
printf("(AR4) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);

foo2(p,r);
printf("(AR5) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);

r++;
printf("(AR6) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);

return 0;
}

This produces the following output:

Code (Text):

(AR3) x = 5, y = 2, *p = 5, *r = 2
(AR1) r = 7, a = 7
(AR4) x = 5, y = 2, *p = 5, *r = 2
(AR2) *a = 10, *b = 10
(AR5) x = 10, y = 2, *p = 10, *r = 2
(AR6) x = 10, y = 2, *p = 10, *r = 10

Activation record 6 is of some interest. For some reason, when $r++$ is read, the pointer $r$ decides to point to the same value $p$ is pointing to (which is $x = 10$).

Why does this happen?

Executing $r++$ again interestingly made $r$ point to zero.

2. Oct 21, 2014

### milesyoung

'r' is of type 'pointer to int', i.e. it stores a memory address. When you execute 'r++', you're doing pointer arithmetic - you're increasing the memory address stored in 'r' by sizeof(int). That so happens to be the address of 'x'.

3. Oct 21, 2014

### milesyoung

As a sidenote: If you want to know why incrementing 'r' makes it point to 'x', you should look up how variables are allocated on the stack and how that's typically organized in memory for your platform.

4. Oct 21, 2014

### Staff: Mentor

There's a phrase that's useful to memorize:
Assuming that ptr is a pointer variable, then the expressions ptr + 1 and ptr++ will have different values depending on how ptr is declared.

If ptr is of type char *, then ptr + 1 and ptr++ both contain the address of the next byte in memory (assuming a char is a single byte).
If ptr is of type int *, then ptr + 1 and ptr++ both contain the address of the next int in memory, which likely will be four bytes higher in memory, assuming an int is four bytes.

Pointer decementing and subtracting an int value from a pointer variable work in a similar way.

5. Oct 23, 2014

### Zondrina

Thank you for making that apparent. So if I have n ints (not in an array) then ptr++ will point to the next integer (likely sizeof(int) higher in memory). I found that weird and counter-intuitive.

Usually we use a pointer to the address of the zero'ith element in an array (&arr[0] == arr). Makes more sense to do it that way anyway.

6. Oct 24, 2014

### milesyoung

You have no guarantee of this. Arrays in C are contiguous in the (virtual) memory space of your application, but variables with local scope, like your 'x', can be allocated however your compiler sees fit. 'ptr++' might point to garbage or perhaps even a virtual memory page that has no physical mapping yet, which will you give you a run-time error when you try to access it.

With that said, it's typical for most C compilers to allocate local variables, in order of appearance, in a LIFO structure in low memory (the stack), which grows "downwards" in memory from high to low memory addresses. Assuming a 4-byte int, the stack frame for 'main' in your application might look like this:

00000000, 'r'
00000004, 'p'
00000008, 'y'
0000000C, 'x'

So 'r' and 'r++' contain 0x8 and 0xC, respectively.

7. Oct 24, 2014

### Zondrina

I wonder why C99 does this; p++ could point you to the next address of a local variable, or it could go boom and point essentially nowhere. Pointer arithmetic on anything except array names seems to be tacky.

8. Oct 24, 2014

### nsaspook

It's 'tacky' when abused but when used in the right context (operating systems,embedded design,etc..) it's elegant.
http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html

9. Oct 24, 2014

### milesyoung

I would agree with nsaspook here. When working "close to the metal" with resource-limited systems, it's very useful to be able to index directly into the address space.

However, it's certainly no secret that C allows you ample freedom in setting up a shot to the foot.

10. Oct 24, 2014

### Staff: Mentor

From the perspective of a developer who is writing applications, there's not much reason for you to use pointer arithmetic (such as incrementing a pointer) for memory that doesn't belong to an array.

From the perspective of someone writing operating system code, which was main reason C was created, there are good reasons, as nsaspook and milesyoung have already mentioned.