I have the following code. Perhaps I have not understood pointer arithmetic as well as I should have but why is int_pointer incremented by 4 instead of by 1? With char_pointer, why isn't it incremented by 4 instead of 1?
#include <stdio.h>
int main() {
int i;
char char_array[5] = {'a', 'b', 'c', 'd', 'e'};
int int_array[5] = {1, 2, 3, 4, 5};
char *char_pointer;
int *int_pointer;
char_pointer = int_array; // The char_pointer and int_pointer now
int_pointer = char_array; // point to incompatible data types.
for(i=0; i < 5; i++) { // Iterate through the int array with the int_pointer.
printf("[integer pointer] points to %p, which contains the char '%c'\n",
int_pointer, *int_pointer);
int_pointer = int_pointer + 1;
}
for(i=0; i < 5; i++) { // Iterate through the char array with the char_pointer.
printf("[char pointer] points to %p, which contains the integer %d\n",
char_pointer, *char_pointer);
char_pointer = char_pointer + 1;
}
}
OUTPUT:
[integer pointer] points to 0xbffff810, which contains the char 'a'
[integer pointer] points to 0xbffff814, which contains the char 'e'
[integer pointer] points to 0xbffff818, which contains the char ' '
[integer pointer] points to 0xbffff81c, which contains the char '
[integer pointer] points to 0xbffff820, which contains the char ' '
[char pointer] points to 0xbffff7f0, which contains the integer 1
[char pointer] points to 0xbffff7f1, which contains the integer 0
[char pointer] points to 0xbffff7f2, which contains the integer 0
[char pointer] points to 0xbffff7f3, which contains the integer 0
[char pointer] points to 0xbffff7f4, which contains the integer 2
That's how pointers aritmetics works: if you increment the pointer by 1, the address gets increased by the size of the pointer type. So since in your machine ints are 4 bytes, incrementing an int pointer increases the address of 4 bytes.
Undefined Behavior
What you have is undefined behavior, first you are violating the strict aliasing rule which basically makes it illegal to access an object through a pointer of a different type, although access through a char * is allowed. I will quote my answer here which covers this more extensively:
the strict aliasing rules which makes it illegal to access an object through a pointer of a different type, although access through a char * is allowed. The compiler is allowed to assume that pointers of different types do not point to the same memory and optimize accordingly. It also means the code invokes undefined behavior and could really do anything.
Second different pointers may have different alignment requirements and so accessing your char array through an int pointer may very well violate this requirement since the char array may not be aligned properly for an int. The draft C99 standard covers this in section 6.3.2.3
Pointers which says (emphasis mine):
A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned57) for the pointed-to type, the behavior is undefined.
A good compiler with the right set of flags should help a lot here, using clang
and the following flags -std=c99 -fsanitize=undefined -Wall -Wextra -Wconversion -pedantic
I see the following warnings (see it live):
warning: incompatible pointer types assigning to 'char *' from 'int [5]' [-Wincompatible-pointer-types]
char_pointer = int_array; // The char_pointer and int_pointer now
^ ~~~~~~~~~
warning: incompatible pointer types assigning to 'int *' from 'char [5]' [-Wincompatible-pointer-types]
int_pointer = char_array; // point to incompatible data types.
^ ~~~~~~~~~~
and during runtime I see the following error:
runtime error: load of misaligned address 0x7fff48833df3 for type 'int', which requires 4 byte alignment
0x7fff48833df3: note: pointer points here
00 e0 3e 83 61 62 63 64 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6d 47 60 5a 1d 7f 00
^
Pointer arithmeic
So pointer arithmetic is based on the size of the type that is being pointed to. How would array access which is basically syntactic sugar for pointer arithmetic work correctly otherwise? You can a read more detailed description here and related discussion here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With