1

I am currently learning the C language and I please you to apologize me if my question is stupid.

As far as I am concerned returning pointers to variables stored in the stack is a bad idea, since the the memory that contains the variable is cleared when the function returns. Hence I expect to get a Segmentation fault when executing the following piece of code:

int *foo()
{
    int j = 5;
    int *ptr = &j;
    return ptr;
}

int main()
{
    int *p;
    p = foo();
    printf("%d\n", *p);

    return 0;
}

However when compiled with gcc (version 8.3.0) the program works apparently fine (no compiler warnings as well) and outputs 5, rather than a Segmentation fault. My question is why does this piece of code work when it is supposed not to.

Thank you in advance!

6
  • 1
    What additional flags did you enable? -Wall -Wextra. Commented May 8, 2020 at 12:04
  • 1
    Your program has undefined behavior, which includes "apparently working fine". The 5 that is output is just a leftover in memory that could be overwritten at any time. Duplicate the printf("%d\n", p); and see what the output on the second printfis. It's probably something else than 5. Commented May 8, 2020 at 12:05
  • I compile with -Wall flag and gcc gives no warning messages.; Commented May 8, 2020 at 12:11
  • When I duplicate printf("%d\n", *p); I get 5 printed two times Commented May 8, 2020 at 12:12
  • @L.Borislavov On my computer I get another number the second time. As I wrote before, it's undefined behavior (google that term). Commented May 8, 2020 at 12:21

2 Answers 2

3

Yes, returning the address of a local variable is a bad idea, as that local (j) ceases to exist when the function returns, and that pointer is now invalid.

However, dereferencing an invalid pointer is not guaranteed to lead to a segfault. The behavior is undefined, which means quite literally anything can happen, including appearing to work correctly.

What’s likely happening is that the portion of the stack that contained j has not yet been overwritten, so the printf just happens to work.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! Now I get it.
3

… the memory that contains the variable is cleared when the function returns…

That is not correct. When the function returns, the storage for its local objects is merely no longer reserved for use for those objects.

The C standard says that, when an object’s lifetime begins, storage (memory) is reserved for it. That means the C implementation provides some memory that can be used for that object, and that it will not use for any other purpose. When the object’s lifetime ends, the C standard says that storage is no longer reserved. The standard does not say that the memory is cleared or unmapped. It also does not say that it is not cleared or that it is not unmapped.

A C implementation could clear the memory, but normal C implementations do not, because that is generally a waste of resources. Most commonly, the memory remains unchanged until it is used for other purposes. But other effects are possible too, such as removing the memory from the process’ virtual address space. So it is normal that you would be able to use the memory after the function returns (and before you call any other functions that alter the memory), but it is also normal that errors would occur in your program if you use the memory. The behavior is not guaranteed either way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.