Object self-destruction

This is a discussion on Object self-destruction within the C++ Programming forums, part of the General Programming Boards category; Hi there, I've got two simple questions. 1. Is "delete this" safe (I'm reading it is!?), assumming method will return ...

  1. #1
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    682

    Object self-destruction

    Hi there,

    I've got two simple questions.

    1. Is "delete this" safe (I'm reading it is!?), assumming method will return (void) immediately after deleting.

    2. Is the following code safe:

    Code:
    void Layer::StrangeDelete()
    {
        shared_ptr<Layer> lockme = this_ptr(); // lockme holds shared_ptr to this now
        _Parent->DeleteChild(); // delete original shared_ptr
        // lockme goes out of scope and there is no more strong references
        // "delete this" will take place, but it is no longer in the method scope, so is it safe or not?
    }
    Thanks
    I never put signature, but I decided to make an exception.

  2. #2
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    a guess..but i read that it is unsafe...
    because you might call the destructor twice..well this I know for simple objects..maybe its the same concept?
    You ended that sentence with a preposition...Bastard!

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,717
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    682
    Thanks, that helped.
    I never put signature, but I decided to make an exception.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by laserlight View Post
    I'm not quite sure why #4 is bad?

    You must be absolutely 100% positive sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it.
    De-referencing it would obviously be bad, but a pointer is just an integer of a memory address, so how can comparing it to NULL be harmful (albeit kind of useless, since delete doesn't set it to NULL)?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    454
    Quote Originally Posted by cpjust View Post
    I'm not quite sure why #4 is bad?



    De-referencing it would obviously be bad, but a pointer is just an integer of a memory address, so how can comparing it to NULL be harmful (albeit kind of useless, since delete doesn't set it to NULL)?
    delete doesn't set a pointer to NULL, your pointer still points to that address. Delete just tells the computer that the memory is free to use. If that memory hasn't been used by the computer for other purposes yet, your old value still exists there, but there is no guarantee that. If you want your pointer to be NULL, you have to set it yourself After delete.
    Last edited by nimitzhunter; 01-18-2011 at 04:09 PM.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by nimitzhunter View Post
    delete doesn't set a pointer to NULL, your pointer still points to that address. Delete just tells the computer that the memory is free to use. If that memory hasn't been used by the computer for other purposes yet, your old value still exists there, but there is no guarantee that. If you want your pointer to be NULL, you have to set it yourself After delete.
    I'm pretty sure cpjust understands that! The point being made was simply that such comparisons couldn't possibly be dangerous...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    682
    Yea, comparing and other operations seem to be safe, except casting, which may dereference 'this' (dynamic_cast). Well, calling other (non-virtual) methods should be (?) safe as well, unless they touch any member variables (despite of the fact that this is useless). And why anyone would need to compare this with NULL if it cannot be explicitly assigned...
    Last edited by kmdv; 01-19-2011 at 04:14 AM.
    I never put signature, but I decided to make an exception.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,290
    Quote Originally Posted by cpjust View Post
    De-referencing it would obviously be bad, but a pointer is just an integer of a memory address, so how can comparing it to NULL be harmful (albeit kind of useless, since delete doesn't set it to NULL)?
    The "#4" rule is possibly being over-cautious, but the point is that "delete this" does not play nicely with a lot of techniques that are often used to give assurances that subsequent code is safe/bugfree/etc.

    To understand "#4" picture a circumstance where a programmer has turned on debugging output while trying to find the cause of a spurious crash.

    He or she comes across code like this .....
    Code:
    if (debugging)
       std::cerr << " Pointer p is " << (void *)p << '\n';
    if (p != NULL)
       p->some_member_function();
    On examining the output, it will be seen that p results in some (non-zero) address. This is immediately followed by a test that p is not NULL protecting the call of the member function. Ergo, our developer concludes the crash cannot be occurring here.

    However, if p has self-destructed ("delete this"), then we have the situation of a programmer assuming code is safe when it is not. A lot of time can be wasted by a developer trying to track down a bug in code that falsely gives reassurance there is no bug.
    Last edited by grumpy; 01-19-2011 at 12:33 PM.
    Right 98% of the time, and don't care about the other 3%.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by grumpy View Post
    The "#4" rule is possibly being over-cautious, but the point is that "delete this" does not play nicely with a lot of techniques that are often used to give assurances that subsequent code is safe/bugfree/etc.

    To understand "#4" picture a circumstance where a programmer has turned on debugging output while trying to find the cause of a spurious crash.

    He or she comes across code like this .....
    Code:
    if (debugging)
       std::cerr << " Pointer p is " << (void *)p << '\n';
    if (p != NULL)
       p->some_member_function();
    On examining the output, it will be seen that p results in some (non-zero) address. This is immediately followed by a test that p is not NULL protecting the call of the member function. Ergo, our developer concludes the crash cannot be occurring here.

    However, if p has self-destructed ("delete this"), then we have the situation of a programmer assuming code is safe when it is not. A lot of time can be wasted by a developer trying to track down a bug in code that falsely gives reassurance there is no bug.
    But that situation can happen whether the object self-deletes or whether you explicitly say 'delete p;' For NULL comparisons to be useful in either case you still have to set the pointer to NULL:
    Code:
    Obj* p = new Obj;
    delete p;
    p = NULL;
    or
    Code:
    Obj* p = new Obj;
    p->Delete();  // Calls delete this;
    p = NULL;
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  11. #11
    Registered User
    Join Date
    Aug 2003
    Posts
    1,205
    The way i see it is that in one case you as the programmer deletes it and thus has the responsibility to not use it, in the other it may be hidden in obscure and hard-to-find places (inside a library for instance) which would make it that much harder to debug.

  12. #12
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by Sebastiani View Post
    I'm pretty sure cpjust understands that! The point being made was simply that such comparisons couldn't possibly be dangerous...
    I've had this argument with folks before, and I'm pretty much squarely on your side. There's no imaginable physical architecture where simply "speaking the name" of invalid memory would cause a problem.

    For one thing, no architecture I know of distinguishes between pointers and integers at the machine code level. So there is no way for the machine to even tell if a given value is a pointer in order to check if it's valid. Second, performing such a check every time a value transfers between registers or memory would be unrealistic.

    I'd pay, oh... $250 to see a problem on any actual architecture.

    On the other hand, you could have a code validator/analyzer like Valgrind that actually tracks this stuff and blows up when someone uses an invalid pointer value -- such as storing it into an array for later use -- but in that case, the explosion is exactly what you want because you're trying to FIND such problems.

    Either way, it isn't something I'd lie awake worrying about.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,290
    Quote Originally Posted by cpjust View Post
    But that situation can happen whether the object self-deletes or whether you explicitly say 'delete p;'
    Sure. That's why I suggest the guideline is over-cautious. I described the type of rationale I've seen offered for that guideline. I did not say I agree with it.

    The basic gist of the set of guidelines is valid, however. An object that deletes itself does tend to seriously break common working assumptions of calling code. Those four guidelines (even the last) basically make it difficult for calling code to assume an object exists after it has actually self-destructed.

    Personally, I prefer objects get deleted by some other containing object, or managed using scope, rather than an object self-destructing.

    I also never set a pointer to NULL after deleting it. Instead, I go out of my way to ensure the pointer also ceases to exist (eg by going out of scope) immediately after the object it points at is destroyed.
    Right 98% of the time, and don't care about the other 3%.

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,304
    Quote Originally Posted by grumpy View Post
    Personally, I prefer objects get deleted by some other containing object, or managed using scope, rather than an object self-destructing.

    I also never set a pointer to NULL after deleting it. Instead, I go out of my way to ensure the pointer also ceases to exist (eg by going out of scope) immediately after the object it points at is destroyed.
    Amen to that one!

    In a code review the other day I caught someone using a SAFE_DELETE macro, which checked for NULL (yuck) and set to NULL (yuck) in addition to the delete. Oh and of course the only place it was called was in the destructor...
    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"

  15. #15
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by grumpy View Post
    Personally, I prefer objects get deleted by some other containing object, or managed using scope, rather than an object self-destructing.
    For the vast majority of pointers, I'd agree with that, but what about pointers to objects created inside DLL's? I don't think it's safe to delete a pointer that was allocated in another module like a DLL. That's why at a previous company they had a Delete() function in the classes returned by factory methods in a DLL.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Texture Management in OpenGL
    By Brafil in forum Game Programming
    Replies: 13
    Last Post: 07-16-2009, 04:32 PM
  2. Order of Object Destruction
    By Tonto in forum C++ Programming
    Replies: 2
    Last Post: 10-11-2006, 08:25 PM
  3. Finding object code
    By kidburla in forum C Programming
    Replies: 3
    Last Post: 11-29-2005, 12:09 PM
  4. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  5. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 13
    Last Post: 10-31-2002, 01:56 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21