#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    26
    Rep Power
    0

    Pointer aritmatic problem


    I'm trying to learn pointer arithmatic, and have a problem what's going on in this textbook example.
    Code:
    #include <stdio.h>
    int main(void){
    int num = 20;
    int *pointer;
    pointer = &num;
    
    printf("*pointer = %d\n", *pointer);
    printf("pointer = %p\n", pointer);
    /*
    increments pointer
    then obtains the value at 
    the new memory address
    */
    printf("*pointer++ = %d\n", *pointer++);
    printf("pointer = %p\n", pointer);
    
    return 0;
    }
    When I run this, I get following results.
    *pointer = 20
    pointer = 0xbf94971c
    *pointer++ = 20
    pointer = 0xbf949720

    >>>>>>>>>>>>>>
    I understand that the pointer address has been incremented by *pointer++, but I do not understand why it is showing the same value for num at this new address, and hope that someone can explain this. I know that it is not a coincidence, as it will do the same after recompiling and running to a 'new' resulting address, or if I change value of num. I would have expected that the value at the new pointer would be some arbitrary value.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,173
    Rep Power
    2222
    Post-increment. Pointer is incremented after it's used to display the contents of the location it's pointing at.

    Nothing in that program is ever done to try to change the value in num. The only thing that's changing is the value of pointer, the memory address that it's pointing to.

    Besides, even if the expression had been (*pointer)++ in order to post-increment num instead of pointer, num wouldn't have been incremented until after the printf, because it's a post-increment.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    26
    Rep Power
    0
    Originally Posted by dwise1_aol
    Post-increment. Pointer is incremented after it's used to display the contents of the location it's pointing at.

    Nothing in that program is ever done to try to change the value in num. The only thing that's changing is the value of pointer, the memory address that it's pointing to.

    Besides, even if the expression had been (*pointer)++ in order to post-increment num instead of pointer, num wouldn't have been incremented until after the printf, because it's a post-increment.
    I'm obviously very confused by this. The 'post increment' is already reflected in the incremented address of printf. Why does the next printf not show the value present in that new address, no matter what it might be, rather than continuing to show the value of the original pointer address? Or, another way that might help clarify my jumbled brain: what code would show me whatever value is actually present at that incremented pointer address? If this were an arrray. if I were to go to an undeclared element, it would get a garbage value. Why is that not happening here?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,173
    Rep Power
    2222
    It's not happening because you're not telling it to do that. Because the printf where you display the contents post-increments the pointer; first it uses the current pointer value and then only when it's done with that statement does it increment the pointer.

    If you want to see what's at that new location, then add another printf:
    printf("*pointer = %d\n", *pointer);
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    26
    Rep Power
    0
    Originally Posted by dwise1_aol
    It's not happening because you're not telling it to do that. Because the printf where you display the contents post-increments the pointer; first it uses the current pointer value and then only when it's done with that statement does it increment the pointer.

    If you want to see what's at that new location, then add another printf:
    printf("*pointer = %d\n", *pointer);
    Yes, that does yield a value of 0 for **pointer, but I'm surprised that it never seems to yield a 'garbage' value. I'm used to seeing garbage values when accessing uninitialized variables. Any simple explanation?
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,173
    Rep Power
    2222
    "**pointer"? I advised a *pointer.

    Whatever makes you think that the "garbage" value isn't zero? Or more specifically, it's whatever value that's pushed onto the stack there for the operation of the function. Since that's dictated by a particular compiler sets that up, we cannot predict what housekeeping value that would be; if we were to research into how your particular compiler formats that stack block, then we could.

    Precede num with the declaration of another int which you do not initialize and see what you get. Then initialize that additional int and see what you get.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    26
    Rep Power
    0
    Originally Posted by dwise1_aol
    "**pointer"? I advised a *pointer.

    Whatever makes you think that the "garbage" value isn't zero? Or more specifically, it's whatever value that's pushed onto the stack there for the operation of the function. Since that's dictated by a particular compiler sets that up, we cannot predict what housekeeping value that would be; if we were to research into how your particular compiler formats that stack block, then we could.

    Precede num with the declaration of another int which you do not initialize and see what you get. Then initialize that additional int and see what you get.
    Seems that you are correct, in that I had already tried that with an array, and, when printed values beyond limit, I did get 0's.
    Seems that, in the past, I always seem to have gotten miscellaneous random numbers.
    Thanks.
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,173
    Rep Power
    2222
    When you wander away from the block of local variables, it is difficult to predict what you may encounter.

    The basic model I've learned in connection with Intel processors is that each function call causes a stack frame to be pushed onto the stack. That stack frame contains the argument values passed to the function, its return address, the stack frame base pointer (bp), saved registers (including the old bp) and local variables, and other temporary storage. I referred to most of that as "housekeeping values". If you write outside the bounds of a local variable, then you might overwrite (AKA "clobber") one of those housekeeping values, which could very likely cause the program to crash; this is how buffer overflow exploits are based on.

    There is nothing in the standard dictating the format of the stack frame nor even that a stack must be used in function calls, so the exact format depends on the compiler. If you want to discover the stack frame format for your particular compiler, then you will need to research it and/or generate assembly listings of a function call to see how the code sets up the stack frame.

    Other than to satisfy your curiosity, there is no practical nor constructive need to know what lies in the stack frame outside the arguments and the local variables.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    26
    Rep Power
    0
    [quote]Precede num with the declaration of another int which you do not initialize and see what you get. Then initialize that additional int and see what you get.[quote]

    Indeed, got 'garbage' value from uninitialized var. Funnier thing that I discovered is that when I ran my compiler with a 'make' command, it refused to compile (I guess all the suffixes after clang were the 'picky problem). Had to run only clang in order to succesfully compile and get that value.

IMN logo majestic logo threadwatch logo seochat tools logo