"char str[5]" reserves 5 bytes of memory for the string.
The first is str[0] = *(str + 0) and the last is str[4] = *(str + 4).
You write to *(str + 5) which is outside the array. It it pure luck that it works.
"str" is not a pointer, it is the start address of the array. "str" behaves almost like a pointer, but you can't assign a value to it.
"char *str" only defines only the pointer, no space for the characters.
A function local variable of type "auto" (default) has random/unknown data before a value is assigned.
When you do *(str + i) = 'M' you write to a random address.
You can do this to make the pointer version to work:
char my_string[6];
char *str = my_string;