Wednesday, April 6, 2011

Is it safe to `delete this`?

In my initial basic tests it is perfectly safe to do so. However, it has struck me that attempting to manipulate this later in a function that deletes this could be a runtime error. Is this true, and is it normally safe to delete this? or are there only certain cases wherein it is safe?

From stackoverflow
  • Yes. It should be perfectly fine. "This" is just a pointer. Any pointer will do for delete. The information on how to delete an object is contained in the heap records. This is how IUnknown::Release() is usually implemented in COM objects.

  • It's safe to delete "this" as long as it's essentially the last operation in the method. In fact several professional level APIs do so (see ATL's CComObject implementation for an example).

    The only danger is attempting to access any other member data after calling "delete this". This is certainly unsafe.

  • Read for a similiar discussion. Your understanding is right in that it does work, is needed, and can be dangerous since you can't access this afterwards.

  • delete this is legal and does what you would expect: it calls your class's destructor and free the underlying memory. After delete this returns, your this pointer value does not change, so it is now a dangling pointer that should not be dereferenced. That includes implicit dereferencing using the class's member variables.

    It is usually found in reference-counted classes that, when the ref-count is decremented to 0, the DecrementRefCount()/Release()/whatever member function calls delete this.

    delete this is typically considered very bad form for many reasons. It is easy to accidentally access member variables after delete this. Caller code might not realize your object has self-destructed.

    Also, delete this is a "code smell" that your code might not have a symmetric strategy for object ownership (who allocates and who deletes). An object could not have allocated itself with new, so calling delete this means that class A is allocating an object, but class B is later freeing it[self].

    Steve Rowe : Technically, your last paragraph is incorrect. While it is true that an object could not have allocated itself, this doesn't imply where you go next. It does not therefore follow that a different class allocated it. A static factory method on the same class could have done the creation.
    Johannes Schaub - litb : "delete this is typically considered very bad form for many reasons." i think that is why well designed ref-counted classes do not use delete this; . they use the handle/body idiom. in my opinion, using delete this is almost always a bad idea. (well, i don't know *any* reason - but im being careful)
  • delete this can cause an issue when you have subclasses of the object you are deleting. Remember construction starts from top down and deletion starts from bottom up. So if delete this is in the middle of the hierarchy you basically lost all the objects below this particular class.

    delete this comes very handy when you are implementing a reference counted object, an example of which is the COM classes.

    1800 INFORMATION : What do you mean when you say "you have basically lost all the objects below this particular class? Can you explain this? Perhaps provide an example?
    Robert Gould : Your example is only true if you don't use virtual destructor. So in a sense you are totally right, but then again a hirarchy withou virtual destructors is pure evil, so one 'should' never see it happen.
  • Delete this is perfectly legal as others have already mentioned. It is risky for one additional reason that hasn't been mentioned yet - you are assuming that the object has been allocated on the heap. This can be difficult to guarantee, although in the case of reference counting implementations isn't generally a problem.

    Steve Rowe : Great point. "delete this" should really only be done if you know for certain how the object was created. This usually means having a private constructor of some sort.
    Cristián Romo : In my case, it's inside a state machine, so when the current state is done, it makes a new state and replaces the only pointer to it in the state handler and then `delete this`s itself.
    hacken : The "proper" solution is to have a private destructor. The object can then call delete this, but you can not establish a stack based version.
    Cristián Romo : Ah, I see. Clever.
  • As stated by others, delete this is a valid idiom but for it to be safe you have to ensure that the object is never instantiated on the stack.

    One way to do this is to make both the constructor and the destructor private and enforce object creation through a class factory function which creates the the object on the heap and returns a pointer to it. The class factory can be a static member function or a friend function. Cleanup can then be done through a Delete() method on the object that does the "delete this". COM objects basically work this way except that in addition they are reference counted with the "delete this" occurring when the reference count is decremented to zero.

  • but dont do it in the destructor !

    Constantin : ...or in constructor :)
    Cristián Romo : Yeah, that'd be bad.
  • Exact Duplicate click here. I had asked the same question.

    Cristián Romo : It's not quite a dupe though, you asked what it's uses are, I asked if it's safe. That to me seems like to different questions.
    Vinay : Even I have asked same way. Is it safe to call. I have pasted the line from the question - In the destructor there is a statement like "delete this". I think, this call will be recursive. Why it is working?
    Cristián Romo : Yes, but you are asking about a specific case, I'm asking in the general case.
  • Legal Yes
    Safe No

0 comments:

Post a Comment