4

I'm wondering if a C pointer can point to a value in an inner block and then dereference the pointer after the inner block ends?

#include <stdio.h>

int main() {
    int a = 42;
    int *r;
    {
        int b = 43;
        r = &b;
    }
    int c = 44;
    printf("%d\n", c);  // Output: 44

    // Is this OK?
    printf("%d\n", *r); // Output: 43
    return 0;
}

Am I getting the output "43" by luck or by design? Does C language specification say something about this situation? (Note that I'm not asking what a specific C compiler behaves)

Yan
  • 117
  • 5
  • 4
    You are lucky (or unlucky, depending on your point-of view) to get an output of 43. Accessing a variable after its lifetime has ended - as you are doing - is undefined behaviour. – Adrian Mole Jul 01 '23 at 14:12
  • 1
    In an ideal situation, *r would actually point to the address of c, giving you an output of 44. Because theoretically, c would overwrite b on the stack but the pointer would still point to the same location. But this is compiler dependent not defined by the language standard. – Irelia Jul 01 '23 at 16:42

3 Answers3

4

This is not allowed. You were "lucky" you got an output of 43.

The lifetime of b ends after the scope it which it was declared ended, and accessing a variable whose lifetime has ended triggers undefined behavior.

This is described in section 6.2.4p2 of the C language:

The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

dbush
  • 205,898
  • 23
  • 218
  • 273
3

If you declare a pointer inside an inner block and assign it the address of a variable within that block, attempting to dereference that pointer outside the block will result in undefined behavior. The memory location that the pointer was pointing to may no longer be valid or may be used for other purposes.

NubDev
  • 506
  • 11
  • 1
    You've misworded this because what you've literally described will produce a compilation error, not a run-time undependability. Taking your words at face value, you will get a compiler error because the variable declared in the inner block is not visible in the enclosing scope following that block. But that's **not** the situation that was described in the question, even though it's what your answer is talking about. – tchrist Jul 02 '23 at 18:41
2

The code has undefined behavior because the pointer r has become invalid when leaving the scope where b is defined. You only got 43 by chance, which is not exactly luck as the undefined behavior went unnoticed and may strike later in more dire circumstances.

chqrlie
  • 131,814
  • 10
  • 121
  • 189