Returning a Pointer of a Local Variable C++

returning a local variable from function in C

The issue here is that when you create the local variable it is allocated on the stack and is therefore unavailable once the function finishes execution (implementation varies here). The preferable way would be to use malloc() to reserve non-local memory. the danger here is that you have to deallocate (free()) everything you allocated using malloc(), and if you forget, you create a memory leak.

C - function returning a pointer to a local variable

Every time you call abc it "marks" a region at the top of the stack as the place where it will write all of its local variables. It does that by moving the pointer that indicates where the top of stack is. That region is called the stack frame. When the function returns, it indicates that it does not want to use that region anymore by moving the stack pointer to where it was originally. As a result, if you call other functions afterwards, they will reuse that region of the stack for their own purposes. But in your case, you haven't called any other functions yet. So that region of the stack is left in the same state.

All the above explain the behavior of your code. It is not necessary that all C compilers implement functions that way and therefore you should not rely on that behavior.

Return a pointer that points to a local variable

The following happens:

  1. Within func1, you created the local x variable and initialised it with a value, i.e. x is on the stack now.
  2. You get the address of x and return it to main.
  3. While returning, func1 and its variables x (and, irrelevant to the question, y) are freed, or popped off the stack, i.e. their memory locations are not reserved any more to hold their values. After this, any other part of the program is allowed to use the memory space that was allocated for x within func1, as func1 isn't active any more.
  4. Your first printf call still happens to see the old value of the memory location where x used to be (but this is not guaranteed) and
  5. the second printf call makes it apparent that something else (with the value of 0, such as the first printf's return value as described by R. Joiny) is (or was) using the same address as x within func1.

This article of the C Programming Boot Camp pretty much describes your situation:

A key to understanding the stack is the notion that when a function
exits, all of its variables are popped off of the stack (and hence
lost forever). Thus stack variables are local in nature. This is
related to a concept we saw earlier known as variable scope, or local
vs global variables. A common bug in C programming is attempting to
access a variable that was created on the stack inside some function,
from a place in your program outside of that function (i.e. after that
function has exited).

Returning a pointer of a local variable C++

Use the new operator

int * count()
{
int myInt = 5;

int * p = new int;
*p = myInt;

return p;
}

As pointed out in other answers this is generally a bad idea. If you must do it this way then maybe you can use a smart pointer. See this question for how to do this
What is a smart pointer and when should I use one?

Is returning a pointer to a local variable always undefined behavior

Returning a pointer to a non-static function local variables will cause the pointer you get at the call site to be a dangling pointer and using it will have undefined behavior.

Here, this is not the case. A string literal has static storage duration, meaning it will live until the end of the program. This means it is safe to return a pointer to a string literal that was declared in a function.

So both foo and func are safe, but if you had

const char * bar()
{
std::string text = "some text";
// stuff
return text.c_str();
}

Then you would be returning a pointer to an object that no longer exits and would have UB trying to read from that returned pointer.

C - Returning a local pointer vs local variable

The behaviour of both functions foo1 and foo2 are undefined, in both C and C++.

You are not allowed to dereference a pointer that points to a variable with automatic storage duration that's no longer in scope.

Tomorrow, foo2() may well give you an error too. Or the compiler might eat your cat.

Why is it bad practice to return a pointer to a local variable or parameter?

It's not so much a "bad practice" (implying that it might cause problems) as much as it is a practice that will absolutely cause undefined behavior. It's like dereferencing a null pointer: don't do it and expect your program to behave within the limits of logic.

Explanation:

When a local variable (including a parameter) is declared, it is given automatic storage, meaning that the compiler takes care of allocating memory for the variable and then deallocating that memory without any effort on the part of the programmer.

void foo(int bar)
{
int baz;
} //baz and bar dissappear here

When the variables' lifetime ends (such as when the function returns), the compiler fulfills its promise and all automatic variables that were local to the function are destroyed. This means that any pointers to those variables now point to garbage memory that the program considers "free" to do whatever it wants with.

When returning a value, this isn't a problem: the program finds a new place to put the value.

int foo(int bar)
{
int baz = 6;
return baz + bar; //baz + bar copied to new memory location outside of foo
} //baz and bar disapear

When you return a pointer, the value of pointer is copied as normal. However, the pointer still points to the same location which is now garbage:

int* foo(int bar)
{
int baz = 6;
baz += bar;
return &baz; //(&baz) copied to new memory location outside of foo
} //baz and bar disapear! &baz is now garbage memory!

Accessing this memory is undefined behavior, so your program will almost certainly misbehave in some way or another. For instance, I once fell victim to this exact problem, and while my program did not crash or terminate, my variables began degrading into garbage values as the compiler overwrote the "free" memory.

Can I return local pointer to main function?

Since the array you point to will go out of scope and cease to exist, attempting to dereference the returned pointer will lead to undefined behavior.

However, in practice the memory will still exist, and if none of the contents have been overwritten by later function calls, it will still be there unmodified. So if you attempt to dereference the pointer you will still see the data. But you should not do that!

Regarding what you're doing, you're not actually dereferencing the pointer, so you don't have UB. All you're doing is printing the value of the pointer itself.



Related Topics



Leave a reply



Submit