Search code examples
cpointers64-bitmemory-address

I don't understand why some pointer addresses are like this


I'm studying pointer in C language and I have some questions.

#include <stdio.h>

int main()
{
    char c = 'A';
    char* pc = &c;
    char** ppc = &pc;

    printf("%p %p\n", pc, ppc);
    printf("%p %p\n", pc + 1, ppc + 1);
    printf("%p %p\n", &c, &c + 1);
    printf("%p %p\n", &pc, &ppc);
    printf("%p %p\n", &pc + 1, &ppc + 1);

    return 0;
}

In this code, let's say that

&c = 0117FE7B
&pc = 0117FE6C
&ppc = 0117FE60

I thought some answers will be like this:

ppc + 1 = 0117FE6D
&pc + 1 = 0117FE6D
&ppc + 1 = 0117FE61

but the correct answer was like this:

ppc + 1 = 0117FE70
&pc + 1 = 0117FE70
&ppc + 1 = 0117FE64

and I don't understand why. Can someone explain this for me? (My computer is using 64 bit windows OS.)


Solution

  • Pointer arithmetic is done in terms objects, not bytes. If p evaluates to the address of a 4-byte int object, then p + 1 evaluates to the address of the next 4-byte int, not the next byte:

    int x;           // assume 4-byte int
    int *ip = &x;
    
    short s;         // assume 2-byte short
    short *sp = &s;
    
    char c;
    char *cp = &c;
    
        +---+                  +---+                   +---+
    x : |   | <-- ip       s : |   | <-- sp        c : |   | <-- cp
        +---+                  +---+                   +---+
        |   |                  |   |                   |   | <-- cp + 1
        +---+                  +---+                   +---+
        |   |                  |   | <-- sp + 1        |   |
        +---+                  +---+                   +---+
        |   |                  |   |                   |   |
        +---+                  +---+                   +---+
        |   | <-- ip + 1       |   |                   |   |
        +---+                  +---+                   +---+
        |   |                  |   |                   |   |
        +---+                  +---+                   +---+
        |   |                  |   |                   |   |
        +---+                  +---+                   +---+
        |   |                  |   |                   |   |
        +---+                  +---+                   +---+
    

    So depending on the size of the pointed-to type, p + 1 will either give the address + 1, or the address + 4, or the address + 8, etc.

    Remember, the array subscript operation a[i] is defined as *(a + i) - given a starting address a, offset i objects (not bytes!!) from that address and deference the result.