Ivan
Ivan

Reputation: 1455

About Heap and Scope

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 :) ...

Upvotes: 0

Views: 113

Answers (3)

alagner
alagner

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

eerorika
eerorika

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:

  • Expected
  • Unexpected
  • Something that you consider "right"
  • Something that you consider "wrong"
  • Always the same behaviour
  • Never the same behaviour
  • Seemingly deterministic
  • Nondeterministic
  • Random
  • Not random
  • Always the correct behaviour that you want, except when you deploy it into production and take a vacation
  • Anything that wasn't listed above

Upvotes: 4

Abdur Rakib
Abdur Rakib

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

Related Questions