c++ – Is it legal to do 'delete this' in a member function?

Question:

The delete this language is for an object to commit suicide. For example:

void Recurso::release() {
    --refs;
    if (refs == 0)
        delete this;

    // Aqui o 'this' pode ser um ponteiro inválido,
    // tocar o objeto por qualquer meio seria errado.
}

What happens here is that the function was called on a valid object and the object's life ended during the execution of the function. Is it permissible and legal for an object's life to end while a member function is running?

This other case shows a call on an invalid object (in this memory there is no MyObj within its lifetime).

void MyObj::noop() {
    // Não vou tocar no 'this' aqui!
}

MyObj* obj = (MyObj*)0xDEADBEEF;
obj->noop();

Is this code valid? If not, why would delete this be valid since the result is effectively the same?

Another example:

MyObj* obj;

void destroyObj() { delete obj; }
void MyObj::func() { destroyObj(); }

int main() { obj = new MyObj; obj->func(); }

Although a delete this does not occur, the example is similar in that the object is destroyed inside func() .

Whether or not a polymorphic object is this allowed?

For any real implementation this is fine as long as the object is not accessed after destruction. But there may be an undefined behavior hiding here.

In the eyes of the standard, can you? (preferably try with excerpts from it)

I don't want to get into the merits of whether or not this is good practice. (it is not!)

Answer:

According to this standard draft , section 9.3.1 ( Nonstatic member functions ), item 2:

If a non-static member function of a class X is called an object that is not of type X, or of a type derived from X, the behavior is undefined.

That is, calling a non-static member function of a class X on an object that is not of class X (or derived) results in undefined behavior. There is no exception for functions that do not access this or any member variable or function.

In the first case, after the delete , this keeps pointing to where there was a valid object, but memory has already been returned to the system pool . Therefore it is not guaranteed that there is a valid object there. As I understand it, this would fit this rule if any member function were called after the delete , even if it was a function that didn't access the members.

In the second case, clearly the invalid address does not point to an object of the specified class, so it is not a valid object. It falls under the rule of undefined behavior.

But in practice, this will all work because it doesn't read anything from invalid addresses.

Inspirational/Adapted answer to this question in English .

Scroll to Top