char* x = "hello";
DOES NOT allocate memory, it simply creates a string literal in memory and puts the address of the first character in x.
When you declare a character array you can do it in 4 ways:
1) String Literal
Length of string = 5
char name[] = "Hank";
The null terminator is added automatically
2) char list
Length of string = 5
char name[] = {'H','a','n','k','\0'};
The null terminator must be added manually.
3) pointer
Length of string = 5
char* name = malloc(sizeof(char)*5);
strcpy(name,"Hank");
4) pointer literal
Length of string = 5
char* name = "Hank";
HOWEVER you cannot change the string now:
strcpy(name,"Billy"); will cause a segfault because you didn't allocate memory to write to.
In both instances name is just a pointer to the beginning of the array, as such:
printf("%c",*name) will print the first character. There are no 'Strings' in C, just arrays of characters. The Null terminator is used to end the array.
Without the null terminator (that's the '\0') you will run into MANY MANY segfaults (A segfault is when your program accesses memory outside of it's boundaries).
The difference between using pointers and using arrays lie in the fact that arrays are static, meaning once your program is compiled you can't change the size of an array. You can however change the size of an array if it was creating using pointers and malloc. The downside to this is that you become responsible for "Freeing" your own memory.
Here's some code examples to show you what I mean.
http://pastebin.com/MxXJQAiR