Thread: Dereferencing

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    26

    Dereferencing

    Code:
    \*It is assumed that the addresses of the
    variables i, j and the first element of the integer array num in hexadecimal are
    22FF6C, 22FF68, 22FF40 respectively.*\
    
    int i, j = 3;
    int *pi = &i, *pj = &j;
    int num[5]={25, -1, 3, 12, 100};
    printf("%x, %x, %x\n", &i, &j, num);
    printf("%x, %x\n", pi, pj);
    j++;
    *pj *= 3;
    printf("%x, %d\n", pj, *pj);
    pi = num;
    num[0] += 5;
    printf("%x, %d\n", pi, *pi);
    printf("%x, %d\n", pi+j, *pi+j);
    *pj = *pj - 8;
    printf("%x, %d\n", pj, *pj);
    printf("%x, %d\n", pi+num[2], *(pi+num[2]));
    I've printed all correct upto the last point. For , pi+num[2], I got 22ff1c. For *(pi+num[2]), what values are used? I thought it would have been 30+3 = 33 but it's 12. Surely if adding three address and then finding the value would give 33?

    Can someone help me with my confusion? Thanks in advance.

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Firstly you should be using %p to print pointers (with a cast to void *).

    Secondly,
    30 + 3
    Would be
    printf("%x, %d\n", pi+num[2], *(pi) + num[2]);

    Otherwise,
    printf("%x, %d\n", pi+num[2], *(pi+num[2]));

    Is, num[0 + 3] (where 3 == num[2]). Which is the same as, *(p + 3) in this case.

    (Brackets for emphasis )
    Last edited by zacs7; 05-13-2009 at 05:24 AM.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    26
    Quote Originally Posted by zacs7 View Post
    Firstly you should be using %p to print pointers (with a cast to void *).

    Secondly,
    30 + 3
    Would be
    printf("%x, %d\n", pi+num[2], *(pi) + num[2]);

    Otherwise,
    printf("%x, %d\n", pi+num[2], *(pi+num[2]));

    Is, num[0 + 3] (where 3 == num[2]). Which is the same as, *(p + 3) in this case.

    (Brackets for emphasis )
    But *(p+3) would give *(22ff10 + 3) = *(22ff13) which still would be 31 and not 12. I'm not understanding where 12 is comming from.

    I assume *(22ff1c )=12 but just given *(22ff1c) how would I be able to see that this is 12.

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    > But *(pi+3) would give *(22ff10 + 3) = *(22ff13) which still would be 31 and not 12.
    No, it is not.

    Here's a nice little table,
    Code:
                ----------------------------
    x           |  0  |  1  | 2  | 3  |  4  |
    *(pi + x)   |  30 | -1  | 3  | 12 | 100 |
                -----------------------------
    Ignore the addresses, they're meaningless for this explanation.

    Of course,
    Code:
    *(pi + 0) = num[0] = 30
    *(pi + 1) = num[1] = -1
    *(pi + 2) = num[2] = 3
    *(pi + 3) = num[3] = 12
    *(pi + 4) = num[4] = 100
    So, using the magic table. *(pi + 3) == num[0 + 3] = 12

    Where do you get the 31 from?!

    Don't forget about operator precedence, "pi" is an address to the first element in num[]. Note: address.. The rules in C of precendence state, in this case, evaluate what's ever in the brackets then dereference this value as an address. That is, *(p + x) means, add p to x and call this "temp", and then dereference "temp". And out pops your value

    > Surely if adding three address and then finding the value would give 33?
    No, that would be 12. Finding the value at address (num[0]) then adding 3 would be 33.
    Last edited by zacs7; 05-13-2009 at 07:15 AM.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    26
    Quote Originally Posted by zacs7 View Post
    > But *(pi+3) would give *(22ff10 + 3) = *(22ff13) which still would be 31 and not 12.
    No, it is not.

    Here's a nice little table,
    Code:
                ----------------------------
    x           |  0  |  1  | 2  | 3  |  4  |
    *(pi + x)   |  30 | -1  | 3  | 12 | 100 |
                -----------------------------
    Ignore the addresses, they're meaningless for this explanation.

    Of course,
    Code:
    *(pi + 0) = num[0] = 30
    *(pi + 1) = num[1] = -1
    *(pi + 2) = num[2] = 3
    *(pi + 3) = num[3] = 12
    *(pi + 4) = num[4] = 100
    So, using the magic table. *(pi + 3) == num[0 + 3] = 12

    Where do you get the 31 from?!

    Don't forget about operator precedence, "pi" is an address to the first element in num[]. Note: address.. The rules in C of precendence state, in this case, evaluate what's ever in the brackets then dereference this value as an address. That is, *(p + x) means, add p to x and call this "temp", and then dereference "temp". And out pops your value

    > Surely if adding three address and then finding the value would give 33?
    No, that would be 12. Finding the value at address (num[0]) then adding 3 would be 33.
    Oh yes, that totally makes sence. We were told that pi was equal to num earlier so:

    pi+num[2] = num+num[2] = num[3] =12

    Thanks a million. I've been confused for quite some time but your explaination has solved my confusion. Thanks once again.
    Last edited by Air; 05-13-2009 at 08:44 AM.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, I would describe this:
    num+num[2]
    as
    num[num[2]]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    26
    Thanks.
    Last edited by Air; 05-13-2009 at 08:48 AM.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Air View Post
    What about?
    num[0]+num[2]
    That will be "28". You are confusing the value of a variable with it's memory address. For example, going back to your Original Post, num+num[2] will be num[3], since the starting address of num is num[0], and the value of num[2] is three. Since num is an int pointer, this will advance the location it points to by the size of three stored ints, a la zacs7's table (num+1=&num[1], num+2=&num[2], etc).

    What did you think "num" is suppose to equal?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-22-2009, 05:03 AM
  2. Replies: 0
    Last Post: 03-20-2008, 07:59 AM
  3. Dereferencing Pointers help
    By Rune Hunter in forum C++ Programming
    Replies: 10
    Last Post: 07-14-2007, 06:43 PM
  4. dereferencing void pointer
    By nkhambal in forum C Programming
    Replies: 4
    Last Post: 04-25-2005, 02:47 AM
  5. Glib and file manipulation
    By unixOZ in forum Linux Programming
    Replies: 1
    Last Post: 03-22-2004, 09:39 PM