1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Weird pointer outcome

  1. Oct 20, 2014 #1

    Zondrina

    User Avatar
    Homework Helper

    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. jcsd
  3. Oct 21, 2014 #2
    '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'.
     
  4. Oct 21, 2014 #3
    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.
     
  5. Oct 21, 2014 #4

    Mark44

    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.
     
  6. Oct 23, 2014 #5

    Zondrina

    User Avatar
    Homework Helper

    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.
     
  7. Oct 24, 2014 #6
    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:

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

    So 'r' and 'r++' contain 0x8 and 0xC, respectively.
     
  8. Oct 24, 2014 #7

    Zondrina

    User Avatar
    Homework Helper

    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.
     
  9. Oct 24, 2014 #8

    nsaspook

    User Avatar
    Science Advisor

    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
     
  10. Oct 24, 2014 #9
    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.
     
  11. Oct 24, 2014 #10

    Mark44

    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.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Weird pointer outcome
  1. C pointer question (Replies: 1)

Loading...