Referencing a char* that went out of scope
Inside the scope where b
is defined, it is assigned the address of a string literal. These literals typically live in a read-only section of memory as opposed to the stack.
When you do a=b
you assign the value of b
to a
, i.e. a
now contains the address of a string literal. This address is still valid after b
goes out of scope.
If you had taken the address of b
and then attempted to dereference that address, then you would invoke undefined behavior.
So your code is valid and does not invoke undefined behavior, but the following does:
int *a = NULL;
{
int b = 6;
a = &b;
}
printf("b=%d\n", *a);
Another, more subtle example:
char *a = NULL;
{
char b[] = "stackoverflow";
a = b;
}
printf(a);
The difference between this example and yours is that b
, which is an array, decays to a pointer to the first element when assigned to a
. So in this case a
contains the address of a local variable which then goes out of scope.
EDIT:
As a side note, it's bad practice to pass a variable as the first argument of printf
, as that can lead to a format string vulnerability. Better to use a string constant as follows:
printf("%s", a);
Or more simply:
puts(a);
String literals are statically allocated, so the pointer is valid indefinitely. If you had said char b[] = "stackoverflow"
, then you would be allocating a char array on the stack that would become invalid when the scope ended. This difference also shows up for modifying strings: char s[] = "foo"
stack allocates a string that you can modify, whereas char *s = "foo"
only gives you a pointer to a string that can be placed in read-only memory, so modifying it is undefined behaviour.
Line by line, this is what your code does:
char* a = NULL;
a
is a pointer not referencing anything (set to NULL
).
{
char* b = "stackoverflow";
b
is a pointer referencing the static, constant string literal "stackoverflow"
.
a = b;
a
is set to also reference the static, constant string literal "stackoverflow"
.
}
b
is out of scope. But since a
is not referencing b
, then that does not matter (it's just referencing the same static, constant string literal as b
was referencing).
printf(a);
Prints the static, constant string literal "stackoverflow"
referenced by a
.