This declaration:
char s[] = "hello";
Creates *one* object - a `char` array of size 6, called `s`, initialised with the values `'h', 'e', 'l', 'l', 'o', '\0'`. Where this array is allocated in memory, and how long it lives for, depends on where the declaration appears. If the declaration is within a function, it will live until the end of the block that it is declared in, and almost certainly be allocated on the stack; if it's outside a function, it will *probably* be stored within an "initialised data segment" that is loaded from the executable file into writeable memory when the program is run.
On the other hand, this declaration:
char *s ="hello";
Creates *two* objects:
- a **read-only** array of 6 `char`s containing the values `'h', 'e', 'l', 'l', 'o', '\0'`, which has no name and has *static storage duration* (meaning that it lives for the entire life of the program); and
- a variable of type pointer-to-char, called `s`, which is initialised with the location of the first character in that unnamed, read-only array.
The unnamed read-only array is typically located in the "text" segment of the program, which means it is loaded from disk into read-only memory, along with the code itself. The location of the `s` pointer variable in memory depends on where the declaration appears (just like in the first example).