Say I have a simple function that returns a C string this way:
const char * getString()
{
const char * ptr = \"blah blah\";
return ptr;
}
I guess that if it were a local variable, I would not be able to pass it to my main() function... But if it's not, where is it stored?
String literals are usually stored in a read-only data section (.rodata
). C standard just say they have static storage duration. Therefore you can return a pointer to such literal, but it is not the case of arrays.
In the following example, the object pointed by p1
has static storage duration, whereas the array p2
has automatic storage duration.
char *f(void)
{
const char *p1 = "hello, world";
char p2[] = "hello, world";
return p1; /* allowed */
return p2, /* forbidden */
}
You are right in that they are not the same thing. char a[] is an array formed on the stack, and then filled with "blah.." - inside the function, you have essentially `const char a[15]; strcpy(a, "blah blah blah");"
The const char *ptr = "blah blah blah";
on the other hand is simply a pointer (the pointer itself is on the stack), and the pointer points to the string "blah blah blah", which is stored somewhere else [in "read only data" most likely].
You will notice a big difference if you try to alter something, e.g:
a[2] = 'e';
vs ptr[2] = 'e';
- the first one will succeed, because you are modifying a stack value, where the second (probably) will fail, because you are modifying a read only piece of memory, which of course should not work.
When you write
const char *ptr = "blah blah";
then the following happens: the compiler generates a constant string (of type char []
) with the contents "blah blah"
and stores it somewhere in the data segment of the executable (it basically has a similar storage duration to that of variables declared using the static
keyword).
Then, the address of this string, which is valid throughout the lifetime of the program, is stored in the ptr
pointer, which is then returned. All is fine.
Does this mean that
"blah blah"
is not a local variable inside getString()?
Let me respond with a broken English sentence: yes, it isn't.
However, when you declare an array, as in
const char a[] = "blah blah";
then the compiler doesn't generate a static string. (Indeed, this is a somewhat special case when initializing strings.) It then generates code that will allocate a big enough piece of stack memory for the a
array (it's not a pointer!) and will fill it with the bytes of the string. Here a
is actually a local variable and returning its address results in undefined behavior.
So...
But I thought that
const char *ptr
andconst char a[]
were basically the same thing.
No, not at all, because arrays are not pointers.
They are not the same.
The first is a pointer to a string literal. The pointer itself is in automatic storage. The string is in static, read-only memory. It's immutable.
The second is an automatic (stack) char
array (and that return is, as the warning says, not legal).
In your function, the scope of a[]
array is within the function getString2()
. its local array variable.
const char *getString2()
{
const char a[] = "blah blah blah";
return a;
}
In above case string "blah blah blah"
copies fist into a[]
and your are trying to return that array with return a
statement, but not constant string.
Where as in first code getString()
: ptr = "blah blah";
ptr point to memory that has global scope.
const char * getString()
{
const char * ptr = "blah blah";
return ptr;
}
In this case you returns the address of constant string "blah blah"
that is legal to do.
So actually its Scope problem.
it helpful to learn about Memory Layout of C Programs and Variable Scope in C
.