In C, one can use a string literal in a declaration like this:
char s = "hello";
or like this:
char *s = "hello";
So what is the difference? I want to know what actually happens in terms of storage duration, both at compile and run time.
The difference here is that
char *s = "Hello world";
"Hello world" in the read-only parts of the memory, and making
s a pointer to that makes any writing operation on this memory illegal.
char s = "Hello world";
puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. Thus making
s = 'J';
First off, in function arguments, they are exactly equivalent:
void foo(char *x); void foo(char x); // exactly the same in all respects
In other contexts,
char * allocates a pointer, while
char  allocates an array. Where does the string go in the former case, you ask? The compiler secretly allocates a static anonymous array to hold the string literal. So:
char *x = "Foo"; // is approximately equivalent to: static const char __secret_anonymous_array = "Foo"; char *x = (char *) __secret_anonymous_array;
Note that you must not ever attempt to modify the contents of this anonymous array via this pointer; the effects are undefined (often meaning a crash):
x = 'O'; // BAD. DON'T DO THIS.
Using the array syntax directly allocates it into new memory. Thus modification is safe:
char x = "Foo"; x = 'O'; // No problem.
However the array only lives as long as its contaning scope, so if you do this in a function, don’t return or leak a pointer to this array – make a copy instead with
strdup() or similar. If the array is allocated in global scope, of course, no problem.
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
chars 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).