Search code examples
c++linuxoopthis-pointer

After using 'delete this' in a member function I am able to access other member functions. Why?


I just wrote a sample program to see the behaviour of delete this

class A
 {
   ~A() {cout << "In destructor \n ";}
 public: 
    int a;
    A() {cout << "In constructor \n ";}

    void fun()
     {
       cout << "In fun \n";
       delete this;
       cout << this->a << "\n"; // output is 0
       this->fun_2(); // how m able to call fun_2, if delete this is called first ??
     }

   void fun_2()
    {
      cout << "In fun_2 \n";
    }

main()
{
 A *ptr = new A;
 ptr->a = 100;
 ptr->fun(); //delete this will be executed here
 ptr->fun_2(); //how m able to execute fun_2 when this pointer is deleted ??
 cout<< ptr->a << "\n"; //prints 0
 return 0;
}

> Output
In constructor
In fun
In destructor
0
In fun 2
In fun 2
0

Questions

  1. After executing delete this in fun(), how I am able to access func_2() with this pointer in fun() ??
  2. Now in main how I am able to do obj->fun_2 as this pointer is deleted ??
  3. If I am able to access function members after killing this object, then why data members are comming zero '0' ??

m using linux ubuntu and g++ compiler


Solution

  • Let's compare that to a similar szenario:

    A *a= new A();  
    func(a);  
    delete a;  
    func2(a);  
    

    In my sample the compiler just passes the pointer a to func and func2, it does not care if it is pointing to a valid object. So if you call func2(a) and func2 dereferences the pointer, this is undefined behaviour. The program might crash if the memory was released back to the operating system and the program cannot access *a anymore. Normally delete keeps the memory allocated, does not pass it back to the operating system, so accessing *a after delete will not give an exception, but just return any value. This might be the previous values of *a, but it might also be any other value depending on the implementation of delete and depending on other calls to new done between delete a and *a. MSVC for example sets the memory to a predefined pattern in debug mode so you can easily spot when accessing freed memory.

    Why is this related to your question? Because the compilers passes this as a hidden, implicit parameter.