42

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?

Antti Haapala
  • 117,318
  • 21
  • 243
  • 279
Jason
  • 2,917
  • 4
  • 23
  • 27

5 Answers5

100

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.

Community
  • 1
  • 1
GManNickG
  • 459,504
  • 50
  • 465
  • 534
  • 1
    "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*`). – Keith Thompson Jan 13 '16 at 18:57
  • "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"). – Code Abominator Aug 15 '16 at 03:05
  • "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. – Winter Jul 17 '17 at 16:11
  • 1
    @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 Jul 17 '17 at 17:22
  • 1
    @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. :) – GManNickG Jul 17 '17 at 17:27
3

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)

MByD
  • 129,681
  • 25
  • 254
  • 263
1

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)

Pablo
  • 8,408
  • 2
  • 36
  • 29
1

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.

Amir Rachum
  • 67,681
  • 68
  • 159
  • 239
0

A pointer points at the BEGINNING of something in memory. An INT occupies 4 bytes (32bit) and a DOUBLE occupies 8 bytes (64bit) in memory. So if you have a DOUBLE number stored, and you wish at a very low level pointing to the next available memory location, the pointer wooud be increased by 8 bytes. If for some reason you pointed at +4bytes from the start of a DOUBLE value, you would corrupt it's value. Memory is a very large flat field that has no conscience of itself, so it's up to the software to divides it properly and to "respect the borders" of items located in that field.

Paolo
  • 154
  • 8