Reputation: 1455
I have this very simple code:
#include <iostream>
using namespace std;
int main()
{
int *p, *q, u;
{
p = new int(4);
int v = 5;
q = &v;
u= v;
}//End scope 2
cout<< *p << "\n" << *q << "\n" << u;
delete p;
return 0;
}
And the output is:
4
5
5
Pleaso cerrect me if I'm wrong :) ...
p
is pointing to a memory space that was allocated in the heap, this memory won't be affecetd at the "end scope" and will only be dellocated when calling delete
.u
is a hard copy of v
, so there's actually a copy of it's value somewhere else in the stack memory.q
points to the address of v
, which is allocated in the stack and should be erased (?) when leaving the "scope 2", if this is the case, why printing *q
still finds the right value of v
?Upvotes: 0
Views: 113
Reputation: 4062
Bullet no. 3 is clearly undefined behaviour as it has already been mentioned.
Number 1 though is interesting. You are right in the sense it will outlive the scope, and shall be destroyed when delete is called. Turns out however, that as-if rule might apply to heap-allocation, too. Thus, compilers (mostly contemporary ones) are able to optimize new-delete away, as long as they can prove the allocated memory is not used outside the of the scope scope being optimized. In that case: as long as the allocated variable is used as if it were an automatic one.
Thus, should the UB be eliminated from your code:
#include <iostream>
using namespace std;
int main()
{
int *p;
{
p = new int(4);
int v = 5;
}//End scope 2
cout<< *p << "\n";
delete p;
return 0;
}
it turns out that new GCC (tested with 11.2) elides the new-delete pair completely. See here.
My point is: knowing stack/heap is good, but it's the implementation detail. I'd recommend you think also in terms of automatic/static/dynamic lifetime/storage duration of object.
Upvotes: 1
Reputation: 238321
why printing *q still finds the right value of v?
There is no such thing as "right value" for an object that no longer exists.
You observed the behaviour that you did because the behaviour of the program is undefined. You observed one behaviour; the behaviour could have been something else because the language doesn't guarantee this behaviour, but the behaviour wasn't something else because the language doesn't guarantee any other behaviour either.
The behaviour could be any of these:
Upvotes: 4
Reputation: 235
It's undefined behavior. When the code exits a scope, the data and variables in the scope are deleted. But that does not mean the memory space in RAM is completely erased. The compiler de-allocates that memory so that the memory can be used again but the last data just remains there. So, if the memory is not allocated to something else (not necessarily your program), it will still retain the last data. In practice, this rarely happens. But for small snippets like your code, since the memory data is printed almost immediately after de-allocation, it might show the correct data.
Upvotes: 2