Thread: How to delete object itself(a dynamic list) by using a destructor

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    2

    How to delete object itself(a dynamic list) by using a destructor

    Supposed the class's design cannot be changed. There are dynamic list object linked together.

    My destructor doesn't work ,why? Or we cannot use destructor to do so.

    Hope you can help me.

    Code:
    class List{
    public:
        List();
        ~List();
    
    
    private:
        List *left;
        List *right;
        int data;
    
    
    };
    List::~List() {
        if (this == NULL)
            return;
        else {
            if (this->left != NULL) {
                delete this->left;
                left = 0;
            }
            if (this->right != NULL) {
                delete this->right;
                right = NULL;
            }
    
    
            delete this;
        }
    }

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    ?!?!:
    Code:
    if (this == NULL)
    An object should never be testing for its own existence!

    You seem to have missed the fact that this will call the destructor of the same object as it is already destructing.
    Code:
            delete this;
    Hence your destructor has infinite recursion.

    Also, you should not check a pointer for NULL before calling delete. The NULL check is already built into delete itself as the first thing it does.
    Likewise, you also don't NULL out pointer values in a destructor for the same reason you don't twink out every word on a printed document before you shred and burn it. (It's a pointless waste of time). And if you were going to pointlessly do it, you'd at least be consistent and not use a mixture of NULL and zero.

    Finally, what you're trying to do is most easily and correctly accomplished with just two lines inside the destructor, both of which are delete statements, and not a single occurrence of "NULL" in sight.
    Last edited by iMalc; 10-06-2012 at 02:14 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Also I'm going to assume that list isn't a tree and doesn't need to be rotated a million times to delete, but you can delete a list with a simple loop.

    Code:
    while there are still nodes:
    save a pointer to the next node
    delete the current node
    set the current node to the saved pointer
    end while
    Or delete it backwards, who cares.

    I know you said don't change the interface, but this could be the content of a (private) utility function called "Clear".
    Last edited by whiteflags; 10-06-2012 at 02:35 AM.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    This is idiotic.

    Who thought this up?

    Yes, it can be done.

    No. It isn't as simple as these guys have made it.

    It isn't that simple because the structure is broken; a node in a list simply has no business owning itself.

    *shrug*

    That isn't to say it is really all that difficult.

    You need to eliminate the mutual reference; unwind the mutual reference and follow normal procedure.

    [Edit]
    For those that didn't catch the mutual reference: this destructor drives both `left->~List()' and `right->~List()' to call `this->~List()' which is completely insane as `this' is being destroyed three or four times depending on how nodes (`List' objects) are managed.
    [/Edit]

    Soma

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by iMalc View Post
    Hence your destructor has infinite recursion.
    It's actually worse than that. The destructor has infinite recursion if the object begin destroyed was created with operator new, and the destructor has been invoked by the corresponding operator delete. Otherwise the code has undefined behaviour (using operator delete on an object that wasn't created with operator new). Practically, it is still infinitely recursive, but it could also cause any conceivable chaos (eg tromping random memory) on each recursive call.

    That's just a quibble on my part, as everything you say in your spot is absolutely spot on.

    If the original class design can't be changed (bearing in mind that "class design" includes both the interface specification and behavioural specification) then my response would be simple: use another class, even if I have to roll my own.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    Oct 2012
    Posts
    2
    Thank you so much for you guys.
    Does it mean I need to modify the destructor code?? Or deletion cannot be done by destructor and I have to implement a function to do so.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by kobe View Post
    Does it mean I need to modify the destructor code?? Or deletion cannot be done by destructor and I have to implement a function to do so.
    You need to modify the "destructor code". A destructor is a function (albeit a special one) and, like any function, can do deletion.

    The thing is, the destructor is invoked as part of the process of destroying the object. If the destructor is invoked to as part of the process of destroying object X, it should not attempt to initiate destruction of object X. But that is exactly what "delete this" does. The effect is we are destroying X, so delete X, which starts destroying X, which deletes X, which starts destroying X ..... i.e. infinite looping or recursion.

    The other thing is that operator delete has no effect on a NULL pointer - the C++ standard guarantees that. A destructor will never be invoked with this being a NULL pointer either (unless some other code has invoked undefined behaviour, in which case all bets are off). So your various comparisons with NULL are pointless.

    The other thing to realise is that operator delete should not be used on a pointer, unless that pointer came from operator new (and, since there are multiple forms of operator new and delete, the versions also need to line up).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 21
    Last Post: 06-26-2012, 03:33 PM
  2. Keeping a Dynamic Object List and Referencing Them
    By M.Richard Tober in forum C++ Programming
    Replies: 5
    Last Post: 05-29-2011, 06:44 AM
  3. Delete keyword and Destructor problem
    By almawajdeh in forum C++ Programming
    Replies: 4
    Last Post: 12-30-2010, 08:56 AM
  4. delete memory in a struct destructor
    By JeremyCAFE in forum C++ Programming
    Replies: 5
    Last Post: 03-12-2006, 11:34 AM