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.

Tags:

C