destructor / semantics of delete this

Discussion in 'C++' started by Alexander Stippler, Aug 20, 2003.

  1. Hi,

    I have some question about the usage of delete. I have some reference
    counted classes, all derived from SharedObject. It's destructor looks like
    this:

    ~SharedObject()
    {
    if (--references_ == 0) {
    delete this;
    }
    }

    Now I'd like to know if
    a) it's OK to use delete this (especially in the destructor)
    and
    b) my guess, about what happens, is correct.
    In my understanding the destructor is entered and delete this is executed
    (if "if" is entered of course). Delete, as far as I know, calls the
    destructor of the object again, now the if-condition is false and the
    storage is freed due to the first call of delete.
    I may be absolutely wrong. I would not wonder. But what does really happen
    and is it a good idea at all to use delete this.

    regards,
    alex
    Alexander Stippler, Aug 20, 2003
    #1
    1. Advertising

  2. "Alexander Stippler" <-ulm.de> wrote in message
    news:-ulm.de...
    | I have some question about the usage of delete. I have some reference
    | counted classes, all derived from SharedObject. It's destructor looks like
    | this:
    |
    | ~SharedObject()
    | {
    | if (--references_ == 0) {
    | delete this;
    | }
    | }

    This won't work. Once the destructor is executed, it is too late to
    try to cancel the destruction process.
    You need to use a different approach:
    class SharedObject
    {
    public:
    SharedObject() : refCnt(1) {}
    void addRef() { ++refCnt; }
    void release() { if(!--refCnt) delete this; }
    protected:
    virtual ~SharedObject()=0; // abstract class
    private:
    int refCnt;
    };
    SharedObject::~SharedObject() {}

    Such a base class is usually combined with a smart pointer.
    + templates are to be considered for type safety.

    Note that reference-counted classes is a well studied subject in C++.
    Make sure to read advice from Scott Meyers and others on the subject.
    Also, existing implementations such as boost::shared_ptr definitely
    are to be considered:
    http://www.boost.org/libs/smart_ptr/shared_ptr.htm


    | Now I'd like to know if
    | a) it's OK to use delete this (especially in the destructor)
    Yes in rare and specific cases -- but never in the destructor.

    | b) my guess, about what happens, is correct.
    | In my understanding the destructor is entered and delete this is executed
    | (if "if" is entered of course). Delete, as far as I know, calls the
    | destructor of the object again, now the if-condition is false and the
    | storage is freed due to the first call of delete.
    This leads to undefined behavior. Not only is it illegal to call the
    destructor twice. But also, the call to 'delete' will attempt to free
    memory (=> the same memory block will be freed twice, or the call
    will attempt to free a stack-based address... not good at all).


    I hope this helps,
    Ivan Vecerina, Aug 20, 2003
    #2
    1. Advertising

  3. Alexander Stippler

    Chris Theis Guest

    "Alexander Stippler" <-ulm.de> wrote in message
    news:-ulm.de...
    > Hi,
    >
    > I have some question about the usage of delete. I have some reference
    > counted classes, all derived from SharedObject. It's destructor looks like
    > this:
    >
    > ~SharedObject()
    > {
    > if (--references_ == 0) {
    > delete this;
    > }
    > }
    >
    > Now I'd like to know if
    > a) it's OK to use delete this (especially in the destructor)
    > and
    > b) my guess, about what happens, is correct.
    > In my understanding the destructor is entered and delete this is executed
    > (if "if" is entered of course). Delete, as far as I know, calls the
    > destructor of the object again, now the if-condition is false and the
    > storage is freed due to the first call of delete.
    > I may be absolutely wrong. I would not wonder. But what does really happen
    > and is it a good idea at all to use delete this.
    >

    As it's already been pointed out by Ivan it's not a good idea to use delete
    this in a dtor. You will end up in a recursive call of the dtor which stops
    after 2 iterations but still it's illegal to call the dtor of an object
    twice. I'd recommend to read Scott Meyer's article from April 1998 in the
    C++ Users Journal and there are countless others covering this topic. You
    can furthermore refer to the FAQ 16.21 for a brief overview.

    HTH
    Chris
    Chris Theis, Aug 20, 2003
    #3
  4. Alexander Stippler

    Rolf Magnus Guest

    Chris Theis wrote:

    > As it's already been pointed out by Ivan it's not a good idea to use
    > delete this in a dtor. You will end up in a recursive call of the dtor
    > which stops after 2 iterations but still it's illegal to call the dtor
    > of an object twice.


    Not only will the destructor be called twice, but the memory will be
    released twice, unless the object wasn't dynamically allocated. I this
    case, delete is called for an object that never came from new.
    While, depending on the situation, some compilers may let you go away
    with two destructor calls, the other thing almost always results in a
    crash. Generally, none of those things are allowed in C++.
    Rolf Magnus, Aug 20, 2003
    #4
  5. Alexander Stippler

    Agent Mulder Guest

    Agent Mulder, Aug 20, 2003
    #5
  6. > I hope this helps,

    It helped a lot. Thanks
    Alexander Stippler, Aug 20, 2003
    #6
  7. Alexander Stippler

    Chris Theis Guest

    "Rolf Magnus" <> wrote in message
    news:bhvluh$gn1$04$-online.com...
    > Chris Theis wrote:
    >
    > > As it's already been pointed out by Ivan it's not a good idea to use
    > > delete this in a dtor. You will end up in a recursive call of the dtor
    > > which stops after 2 iterations but still it's illegal to call the dtor
    > > of an object twice.

    >
    > Not only will the destructor be called twice, but the memory will be
    > released twice, unless the object wasn't dynamically allocated. I this
    > case, delete is called for an object that never came from new.


    You're of course right on this point, which I should have mentioned for
    completeness.

    > While, depending on the situation, some compilers may let you go away
    > with two destructor calls, the other thing almost always results in a
    > crash. Generally, none of those things are allowed in C++.


    If I get you correctly you indicate that there might be situations
    ("...almost always...") when calling delete twice on an object will not
    result in a crash. Just out of curiosity could you give me an example.

    Regards
    Chris
    Chris Theis, Aug 20, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. frs
    Replies:
    20
    Views:
    736
    Alf P. Steinbach
    Sep 21, 2005
  2. arun
    Replies:
    2
    Views:
    534
    benben
    Jun 13, 2006
  3. Dilip

    Destructor semantics

    Dilip, Sep 27, 2006, in forum: C++
    Replies:
    9
    Views:
    330
    Phlip
    Sep 28, 2006
  4. Jimmy Hartzell
    Replies:
    0
    Views:
    411
    Jimmy Hartzell
    May 19, 2008
  5. Jimmy Hartzell
    Replies:
    2
    Views:
    1,163
    Jimmy Hartzell
    May 20, 2008
Loading...

Share This Page