0

A member of a class is a reference to a local variable. When the local variable is destructed, and the object of this class still exists, you can access the destructed local variable through this object. Why?

  #include <stdio.h>   
    #include <stdlib.h>
    #include <iostream>
    using namespace std;

    class c2
    {
    public:
        int& a;

        c2(int & c):a(c)
        {
        }
    };
    int main()
    {

        c2 * p;
        {
            int i = 20;
            p = new c2(i);
        }
        cout << p->a;


        system("pause");

        return 0;
    }
  • 4
    That's just the way it is. Don't pass references to stuff that will prematurely go out of scope. What happens is undefined behavior, it could be anything. – Sid S Jun 30 '18 at 05:01
  • 5
    Your program exhibits undefined behavior. "Seems to work" is one possible manifestation of undefined behavior. [Nasal demons](http://www.catb.org/jargon/html/N/nasal-demons.html) is another. – Igor Tandetnik Jun 30 '18 at 05:16
  • It's just plain machine voodoo. – Retired Ninja Jun 30 '18 at 05:39
  • @zhangkai - Please also read the answer to [Can a local variable's memory be accessed outside its scope?](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – Bo Persson Jun 30 '18 at 10:52

1 Answers1

2

As pointed out by some comments above, the behavior is actually undefined. See in particular the c++ reference on the Lifetime of a temporary:

a temporary bound to a reference in the initializer used in a new-expression exists until the end of the full expression containing that new-expression, not as long as the initialized object. If the initialized object outlives the full expression, its reference member becomes a dangling reference.

If you use gcc or clang you can compile the program with the option -fsanitize=address: it will crash with

ERROR: AddressSanitizer: stack-use-after-scope

Instead, you will not get any error if you modify your program as follows:

 #include <stdio.h>   
    #include <stdlib.h>
    #include <iostream>
    using namespace std;

    class c2
    {
    public:
        int& a;

        c2(int & c):a(c)
        {
        }
    };
    int main()
    {

        c2 * p;
    {
      int i = 20;
      p = new c2(i);
      cout << p->a;
    }
    delete p;

        return 0;
    }

(In the program I have inserted a delete p to avoid memory leak)

francesco
  • 7,189
  • 7
  • 22
  • 49