Returning a reference to a local variable and its behavior
I am just working with C ++ basics and tried the following lines of code,
int& func()
{
int localnum = 10;
return localnum;
}
int main()
{
int &i = func();
cout<<"value : "<<i<<endl;
cout<<"value : "<<i<<endl;
return 0;
}
Here I am returning a local variable as a reference (which I shouldn't actually be doing, but I did to study the behavior).
I think that even if the execution is func()
complete, the value localnum
will persist and not be destroyed until some process is using the memory space (but sets some bits / flags so that the remaining process treats this chunk of memory as free and can use it) - Correct me , if I am wrong
Just to test this, I print the value i
. In my case, this is the output
value: 10
value: 264952704
It's the same scenario, even if I use a pointer and return an address instead of a link.
My question is, I am not performing any process between these prints, but still the value changes. So any other process on my system is using the memory space localnum
between these prints?
source to share
If you are thinking purely about the language, this is just undefined behavior, so in theory the result could be anything.
Following your implementation reasoning, there is no need for another process to overwrite a local variable normally allocated on the stack. By the way, any call to another function will be executed. In this case, your first call to the operator <<
object cout
involves a function call that reused the stack area that was in use func()
, resulting in overwriting the memory location where the variable localnum
was temporarily created.
But again, the observed result is inconsistent; it depends a lot on implementation, compiler, compiler options, etc.
source to share
Usage <<
involves quite a bit of activity without requiring another process. Check #includes
which one you need in the example program you are pointing from. By the way, the complete code for this will be called "MCVE". https://stackoverflow.com/help/mcve
In fact, the only action that can change "your" stack is the same process , even the same thread in that process. Because each process has its own stack.
The memory you are talking about is the stack. Administration data is nothing more than a pointer to the first usable chunk of memory; and possibly implicit knowledge of how big the stack is as a whole. That is, there are no separate flags for each byte in the stack, which would add a significant amount of stack memory.
For the fact that you only get "10" once, for the same executable code, I suggest the following (compiler depends, but probably generic):
- run the first line with
<<
- read the meaning of i
- put the value somewhere, it won't be overwritten
(maybe a CPU register or somewhere safe on the stack,
that is, the space that is reserved for this purpose in this activity). - use a stack to do streaming
- this overwrites the variable
- but the value is already elsewhere and is safe
- bring it out successfully
- do it all again for the second line,
but this time the value will be overwritten.
Just to reiterate what you yourself and some comments said:
Using the stack after exiting a function is evil.
source to share
I think that although the execution of func () has finished, the localnum value will persist and not be destroyed until some process uses the memory space (but sets some bits / flags so that the remaining process treats this chunk of memory as free and can use it) - Correct me if I am wrong
since this is UB you are not entirely correct. Some compiler may set a bit / flag and another compiler may set the value to zero ... since UB gives each compiler the freedom to do what you like, your explanation is just one of many (although I find this the most common)
My question is, I am not doing any process between these prints, but still the value changes. So any other process on my system is using the localnum memory area between these fingerprints?
If your process doesn't, and the value changes, then yes, someone else changes the value. Note that even if you don't change the value in this address directly, your code can be implemented in a way that changes it behind your back (like the <<<> operator, as Yunnosch said)
Here I am returning a local variable as a reference (which I shouldn't actually be doing, but I did to study the behavior).
I would not recommend learning behavior from the UB case. It is boiled from car to car.
source to share