There is actually a lot going on here. Let's step through it one by one. Consider the following two declarations of the string "Hello ".
char *strA = "Hello "; // #1
char strB[ 7 ] = "Hello "; // #2
The first expression is declaring a character pointer called strA that points to a location in the read-only section of memory where "Hello " (alternatively { 'h', 'e', 'l', 'l', 'o', ' ', '\0' }) is stored. The first declaration is more commonly known as a string literal.
The second expression is declaring an array of characters called strB that consists of seven characters and it is declared on the stack. It's important to note that the convention for strings in C is to have a null terminator (0 character) at the end of a string (an array of characters) -- you are missing this. The initialization syntax (the double quotes) automatically fills the trailing entries with 0s regardless of where it is declared.
Now, to directly answer your question. You cannot overwrite read-only memory and hence if you attempt to modify any memory that strA points to (a string literal) then it will result in an error. You can modify the block of memory that strB points to, however you would want to initialize a larger array to properly accommodate the characters 'w', 'o', 'r', 'l', 'd' and '!'. Compilers will let you write to memory you do not have access to, however there is no guarantee that it will not be allocated to other variables on the same stack frame or another program.
This would be the proper snippet of code:
#include <stdio.h>
int main( void ) {
// Declares an array of characters, strA with a length of 13.
char strA[ 13 ] = "Hello ";
// Concatenates the characters 'w', 'o', 'l', 'r', 'd' and '!' to strA.
strcat( strA, "World!" );
// Outputs to stdout.
printf( "%s", strA ); // => "Hello World!"
return 0;
}