Why does int pointer '++' increment by 4 rather than 1?

37,589

Solution 1

When you increment a T*, it moves sizeof(T) bytes. This is because it doesn't make sense to move any other value: if I'm pointing at an int that's 4 bytes in size, for example, what would incrementing less than 4 leave me with? A partial int mixed with some other data: nonsensical.


Consider this in memory:

    [↓      ]
[...|0 1 2 3|0 1 2 3|...]
[...|int    |int    |...]

Which makes more sense when I increment that pointer? This:

            [↓      ]
[...|0 1 2 3|0 1 2 3|...]
[...|int    |int    |...]

Or this:

      [↓      ]
[...|0 1 2 3|0 1 2 3|...]
[...|int    |int    |...]

The last doesn't actually point an any sort of int. (Technically, then, using that pointer is UB.)

If you really want to move one byte, increment a char*: the size of of char is always one:

int i = 0;
int* p = &i;

char* c = (char*)p;
char x = c[1]; // one byte into an int

†A corollary of this is that you cannot increment void*, because void is an incomplete type.

Solution 2

Pointers are increased by the size of the type they point to, if the pointer points to char, pointer++ will increment pointer by 1, if it points to a 1234 bytes struct, pointer++ will increment the pointer by 1234.

This may be confusing first time you meet it, but actually it make a lot of sense, this is not a special processor feature, but the compiler calculates it during compilation, so when you write pointer+1 the compiler compiles it as pointer + sizeof(*pointer)

Solution 3

As you said, an int pointer points to an int. An int usually takes up 4 bytes and therefore, when you increment the pointer, it points to the "next" int in the memory - i.e., increased by 4 bytes. It acts this way for any size of type. If you have a pointer to type A, then incrementing a A* it will increment by sizeof(A).

Think about it - if you only increment the pointer by 1 byte, than it will point to a middle of an int and I can't think of an opportunity where this is desired.

This behavior is very comfortable when iterating over an array, for example.

Solution 4

The idea is that after incrementing, the pointer points to the next int in memory. Since ints are 4 bytes wide, it is incremented by 4 bytes. In general, a pointer to type T will increment by sizeof(T)

Share:
37,589

Related videos on Youtube

Jason
Author by

Jason

A programming enthusiast who love Open Source. Concise and easy-to-use software tools are my favorite.

Updated on December 14, 2020

Comments

  • Jason
    Jason over 3 years

    Value of a pointer is address of a variable. Why value of an int pointer increased by 4-bytes after the int pointer increased by 1.

    In my opinion, I think value of pointer(address of variable) only increase by 1-byte after pointer increment.

    Test code:

    int a = 1, *ptr;
    ptr = &a;
    printf("%p\n", ptr);
    ptr++;
    printf("%p\n", ptr);
    

    Expected output:

    0xBF8D63B8
    0xBF8D63B9
    

    Actually output:

    0xBF8D63B8
    0xBF8D63BC
    

    EDIT:

    Another question - How to visit the 4 bytes an int occupies one by one?

  • Keith Thompson
    Keith Thompson over 8 years
    "you cannot increment void*, because void is an incomplete type" -- true, but gcc supports arithmetic on void* as an extension (it treats it as if it were char*).
  • Code Abominator
    Code Abominator over 7 years
    "it doesn't make sense" for an integer, almost always, but it makes perfect sense for situations like an array of a variable-length structure ("I have a buffer full of packets, I want to move CurrentPacketPointer to the next packet").
  • Winter
    Winter almost 7 years
    "If you really want to move one byte, increment a char*: the size of of char is always one" No it's not always one, you should use uint8_t instead.
  • GManNickG
    GManNickG almost 7 years
    @Winter: sizeof(char) is always one. It may not always be 8 bits, but it is always 1 byte. In C and C++, a byte is the smallest addressable unit, which is not necessarily always 8 bits.
  • GManNickG
    GManNickG almost 7 years
    @Winter: No worries. It is a good idea to use types such as (u)intN_t when you want a specific layout, such as a byte with 8 bits. :)