@frek,
I just had this conversation with the same example elsewhere.
This can illustrate what's wrong, as others have posted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
#include <iostream>
using namespace std;
int* f() {
int i = 6;
int* p = &i;
return p;
}
void f2()
{
int x = 0;
}
int main()
{
int *p = f();
system("pause"); // or anything to separate instance from use
cout << *p << endl;
f2();
cout << *p << endl;
system("pause");
return 0;
}
| |
If you first test this code in a debugger, and assuming that debugger doesn't complain to you about stack corruption or at least lets you continue, here's what you'll witness:
As before, "*p" will still show 6. Then, the call to f2 will create "x", initializing it to zero.
At which point the next cout of the same "*p" will show 0, because "x" occupies the same place on the stack as "i" once did.
If you then observe this same code in an optimized build, it will behave differently, likely because the two functions f() and f2() will be inlined, so no stack manipulations will happen.
The "obvious rule" is return locals by value so they are copied, and if you must return a pointer, it should be a location calculated as a position inside RAM already owned elsewhere, or if it does represent allocated memory note this places responsibility for ownership on calling code.
Just because this snippet demonstrates curious behavior doesn't mean there's anything "there" to be considered.
It is just the nature of the functioning of the stack, which you could observe using a debugger to better understand what is really happening.
This is also the kind of behavior and observation upon which viruses are designed.