2

I'm studying pointers and I've created this example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

int* f(){
    int n = 10;
    return &n;
}


int main() {
    printf("%d",*f());

}

The expectation were it would not work, because the returned pointer is pointing to a automatic variable, which will be destroyed, and so we'll have a undefined behavior. And my expectations were correct, the program have crashed.

After it I created a similar example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

int* f(){
    int n = 10;
    int* ptr = &n;
    return ptr;
}


int main() {
    printf("%d",*f());

}

The only difference in second example is that the function is returning a variable int* ptr which is of int pointer type, and the initial value of this variable is the address (pointer) of variable int n.

Before running it I thought it wouldn't work too (I thought it would crash again), but it works, the program don't crash and prints the value '10' at the terminal. My question is: Why the second example works if in theory it is pointing to a automatic variable that will be destroyed

[EDIT]

I've read the comments and I've understand that the second example actually is a undefined behaviour. But I'm still with a doubt: Is There any way to force a "fatal" error that demonstrates this example has an undefined behavior "behind the scenes"? I've created other examples like the second, and all of them have a behaviour that seams right (I know, its a undefined behaviour but nothing special have happened, like a crash your a message)

  • 5
    It doesn't "work". It's undefined behavior. One of the possible outcomes of undefined behavior is that things incidentally work as expected, but may also crash under a different compiler or compiler flag, operating system, etc. It's not clear here when you say the first code failed as expected what that actually means. Does it produce an error? Crash? Produce incorrect output? – user229044 Dec 16 '22 at 14:54
  • 1
    Because you're returning the address of the memory allocated to that variable at that time. The address is still a real location even if it no longer applies to a valid variable. – ChrisBD Dec 16 '22 at 14:56
  • 4
    When exiting a function the memory isn't immediately cleared, it's just marked as available. Depending on conditions it may hold the value for a while. It's undefined behavior. – mousetail Dec 16 '22 at 14:56
  • 2
    You answered your own question: undefined behavior. But also, there is a difference in the 2 codes. The 2nd one creates another variable, probably on the stack, which may put `n` in a different location on the stack, so when the function exits, that location is not overwritten. Maybe. – 001 Dec 16 '22 at 14:57
  • It may even crash in a different run of the same program. (Not likely in a program with no inputs, but what program has no inputs?) – ikegami Dec 16 '22 at 15:02
  • 2
    Read this: https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794. It's C++ but it applies exactly to your use case. – Jabberwocky Dec 16 '22 at 15:02
  • Close voter: I wonder why the question has been closed for "needs details or clarity". It is very clear and well written, especially considering the OP is a new SO user. – Jabberwocky Dec 16 '22 at 15:06
  • 2
    *Is There any way to force a "fatal" error that demonstrates this example has an undefined behavior "behind the scenes"?* No, not in general. Undefined behavior is slippery, slippery stuff. When you don't want it to, it causes the worst kinds of problems (segmentation faults, etc.), but then when you want it to fail, as some kind of demonstration, all of a sudden it's like "Neener neener, I'm Undefined Behavior, I can do whatever I want, including 'working correctly'!" – Steve Summit Dec 16 '22 at 16:19
  • The second program works [for certain values of "works"](https://godbolt.org/z/xbsaxG6ao). – n. m. could be an AI Dec 16 '22 at 18:12

0 Answers0