Click here to Skip to main content
15,881,739 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C#
class Str
{
public:   
    void f()
    {
        delete this;
    }

    ~Str()
    {
        cout<<"Inside destructor..."<<endl;
        delete this;
    }
};

I am learning C++ on my own and trying few things.

Why having "delete this;" in destructor causes the program to go to an infinite loop? While it does fine if i do it in a function f() after commenting destructor`s "delete this;" statement?
I am creating object for the class as follows:
Str obj = new Str;
I am using VS compiler for c++.
What is the problem having "delete this" in class destructor??

[enhzflep edit]: Question title, confused: delete this problem ---> confused: "delete(this);" problem
Posted
Updated 22-Feb-12 4:14am
v2

It is going in infinite loop because delete will call detractor and than it go for its own memory release procedure. so when u do this in destroctor it keep calling itself.

To Know more about Delete : http://www.cplusplus.com/reference/std/new/operator%20delete/[^]
 
Share this answer
 
v2
Because delete this; calls object's destructor.
 
Share this answer
 
C#
class Str
{
public:
    void f()
    {
        //Removed: delete this;
    }

    ~Str()
    {
        cout<<"Inside destructor..."<<endl;
        //Removed: delete this;
    }
};


this is your class n u must be creating objects like
C#
Str s = new Str;


the only was to free this memory is by doing
C#
delete s;   //Do this from outside where u did new


from outside the class. as delete s will call the destructor and release memory allocated to S. don't do delete this anywhere inside class.
 
Share this answer
 
The new and delete keywords are new in C++ and they are not available in the C programming language. In C you use
char * pBuf = (char*) malloc(size);
to allocate memory and you have returned a pointer to that memory. When you don't need that memory any more you can free it using
free(pBuf);

In C++ you can do the same using the new and delete keywords.
char *pBuf = new char[size];
// ... do something with pClass
delete [] pBuf;

Here you have created an array of chars and that's why you need to put [] in the delete statement.
The new in C++ is that you can use these keywords to create objects of struct or class types.
CMyClass * pClass = new CMyClass;
// .. do something with pClass
delete pClass;

the new does what malloc does for the size of CMyClass (the memory needed for an instance of CMyClass) and also calls the constructor of CMyClass. The delete keyword calls the destructor of CMyClass and then does what free does (frees the memory allocated for the instance of CMyClass). So when you call delete this in the destructor delete calls first the destructor which calls delete which calls the destructor, which calls delete... and as most functions, the destructor uses stack memory, and after thousands of calls the stack memory is over and the program craches with reason Stack Overflow. This is also called an endless recursion.
 
Share this answer
 
delete this: a.k.a. how to suicide an object!

Unlike many other said, according to the C++ specification calling delete this is not illegal: it simply requires to know what does it mean.

In your case the infinite loop in not due to the delete this inside f() but to the delete this into the destructor.

Calling delete on a pointer actually means do two things:
- call the destructor and ...
- call the operator delete(void*) function, whose default provided implementation actually gives the memory back to the system.

Now, since this is a pointer, delete this has an implicit call to the destructor itself, hence destructors should never call delete this (since you're asking to destroying something is already been destroyed so you destroy it over and over)

About calling delete this into f() (or whatever other function not called by the destructor) this can be accomplished, but requires some cares:
- You must be sure that the object is dynamically allocated: if someone has
{
  Str a;
  a.f();
}

will destroy a that is then automatically re-detroyed at the end of the block (double destruction is technically "undefined behavior", so anything can happen).
- You must ensure that the body of f() will not refer to any Str member variables, or virtual functions, or member function referring member variables, after delete this is called. This is the consequence of the fact that delete destroys the object hence no members exist anymore after that.
- You must ensure no one actually still refer the object you deleted. This is not different than the ususal problem of dangling pointers, but with the fact that who calls f() may be is not expecting an object suicide.

Putting all those requirements together ends up in a situation where you expose an interface (the f() funcntion) having requirements about code you cannot control (what calls f() may be anything, being f() itself public).

So, unless you are in very particular cases, avoid that practice at all. Also for the very simple reason that the most of the programmers will not expect it and understand it.
 
Share this answer
 
v2
Ouch!

Do you often sit on tree branch and then try to saw it off?
Or demolish a house by removing the walls first, leaving the roof in place until last?

If you delete an object in it's own constructor, what do you expect to happen?
 
Share this answer
 
Comments
Anitesh Kumar 22-Feb-12 4:51am    
Thank you for the reply. But could you please help me to understand.. what is the reason for infinite loop?
Anitesh Kumar 22-Feb-12 4:51am    
While calling the same statement through a function doesnot go for loop!!!
OriginalGriff 22-Feb-12 5:00am    
Because the constructor is a special case - it is responsible for creating the object and everything it contains, and ensuring it is in a stable state.
When you delete it, you free all its resources, and call the destructor - both of which assume that the object is fully constructed. The constructor then continues from the point after the delete, assuming that the object still exists. Since it isn't stable in the destructor, and doesn't exist at all after the delete, the system gets confused and can do anything - crash, loop, whatever.
When you delete it from a method, you are not doing that.
CPallini 22-Feb-12 5:03am    
"If you delete an object in it's own constructor"
Do you mean 'destructor', don't you?
Anitesh Kumar 22-Feb-12 5:07am    
Thank you.
In C++, if you do not write a destructor explicitly, the compiler will create a default destructor, which does nothing. When the object is deleted (i.e. delete is called on the object) the destructor is called, and after that the memory used by the object is released.

If you haven't written a destructor, the compiler provided destructor will get executed on object deletion. Since it does not have any code, nothing will happen, and the system will de-allocate the memory used for the object.

If you did write a destructor, the code inside it will get executed when deleting the object, and the memory will get cleared.

You DON'T write delete this inside the destructor. Since delete calls the destructor before clearing the memory, it will get executed in a loop. Now does this clear your problem?

You can use delete this inside a member function. But this is not a good idea either. [Edit: See nv3's comment on this answer too, where he explains that this is not the case always. I did not have that knowledge.]
 
Share this answer
 
v2
Comments
nv3 22-Feb-12 10:39am    
Good explanation, but the last sentence is not entirely correct. MFC for instance uses "delete this" in in the OnNcDestroy member function of Views and mode-less dialogs. The idea is, that a View is created always by "new" and it lives until the user closes the associated window. As there is no other place in the code, where to place the corresponding delete, MFC uses this 'trick' to delete the View when the window is about to die.

But you are right that, except for situation like the one above, it is not a good idea to write "delete this".

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900