The reason this appears to work is because you are incrementing your pointer to point to new spots in memory (which your program may or may not be allocated to use). I am guessing you are declaring this on the stack and that is why your undefined behavior appears to be "ok".
I do not think you understand the power of a pointer and the syntax you used. Remark that the following is equivalent:
int arr[ 2 ] = { 1, 2 };
int *pi = &arr;
// The following output is equivalent to...
for ( int i = 0; i < 2; i++ ) {
printf( "arr[i] = %d.\n", arr[ i ] );
}
// this.
for ( int i = 0; i < 2; i++ ) {
printf( "*(p + i) = %d.\n", *( p + i ) );
}
Consider this, alternate implementation of your code to emphasize how you are pointing to new memory addresses by indexing elements outside of your array.
int *d = ( int * )malloc( 2 * sizeof( int ) );
*( d + 0 ) = 4; // Observe you are accessing the memory location d points to.
*( d + 1 ) = 5; // Observe you are accessing the memory location d + 4 bytes (or 8 if 64-bit) points to...
*( d + 2 ) = 8; // ...
*( d + 3 ) = 9; // ...
*( d + 4 ) = 7; // Observe you are assigning a value to the memory location of d + 24 bytes (or 48 bytes if 64-bit).
for ( int i = 0; i < 5; i++) {
printf( "%d \n", *( d + i ) );
}
Just a quick note on your code. A malloc should typically be followed by a free -- so use it appropriately so there are no memory leaks.
I hope this helped! Feel free to correct me if I made a mistake.