FireAphis
FireAphis

Reputation: 6790

Accessing a local variable after "delete this"

I have a class that employs a reference counting mechanism. The objects of this class are eventually destroyed by calling delete this when the reference count drops to zero. My question is: can I use local on-stack variable after delete this? Here's a more specific example:

class RefCountedClass
{
public:
    RefCountedClass(Mutex& m) :
        mutex_(m)
    {}

    .
    .
    .

private:
    Mutex& mutex_;

    void RemoveReference()
    {
        // As I understand, mutex_ will be destroyed after delete,
        // but using m is all right because it is on-stack and
        // references an external object. Am I right?
        Mutex& m = mutex_; 
        m.Acquire();

        --recount_;
        if (refcount <= 0) delete this;

        m.Release();
    }
};

Upvotes: 7

Views: 639

Answers (4)

Konrad Rudolph
Konrad Rudolph

Reputation: 545686

Yes, you may do this, as long as the member variable itself is really only a reference to an external object.

(Please forgive the previous wrong answer, I was confused about the mutex_ variable.)

Upvotes: 7

user396672
user396672

Reputation: 3166

Yes, you can, but why not to use atomic decrement instead of decrementing the counter under the mutex? And do you actually need to protect (by mutex) object destruction? Indeed, after counter becames 0 the only current thread can acess the object.

So, maybe it is possible to rewrite your code as

     int tmp_count;
     m.Acquire();
        tmp_count= --recount_;
     m.Release();
     if (tmp_count <= 0)  delete this;

(or use atomics to decrement and test the counter)

Upvotes: 1

doron
doron

Reputation: 28892

Generally the only thing you are not allowed to call after delete this is anything that makes a reference to this. This include any non-static class member or function.

In your case, there is a good chance that RemoveReference will not work. This is becuase m points to mutex_ which no longer exists after delete this. Your best bet could well be making mutex_ static.

Edit: Although mutex_ points to an external variable which continues to exist after the class is deleted, there is no bulletproof guarantee that the compiler will not refer back to mutex_ after the class is deleted to obtain the value of the external mutex. There is a good chance that things will work as expected but I do not believe this can be guaranteed.

Upvotes: 0

jab
jab

Reputation: 2984

Yes in this case. Your stack variable 'm' points to an external resource that you get in the constructor

Upvotes: 0

Related Questions