CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Jan 2010
    Posts
    2

    question on "delete"

    Suppose I have a pointer p like this

    int *p = new int(0);
    *p = 100;
    when I try to free the memory, I can do

    delete p;

    I learned that it safe "delete" a 0 (NULL) pointer, but it's undefined behavior to "delete" a pointer twice. So they told me to always add "p=0;" after deleting p.

    Here comes my question:
    It seems that we can just add "p=0" into the implementation of the "delete" operator in order to save some typing for coder and it's much safer. But so far it's not the case. So I am wondering why it's not and what's side effect of this addition. Thank you very much.

  2. #2
    Join Date
    Jan 2009
    Posts
    1,689

    Re: question on "delete"

    C++ is not designed to be safe, it's designed to do exactly what you tell it to. You can simply do this:

    Code:
    #define DELETE(ptr);\
       {\
          delete ptr;\
          ptr = 0;\
       }
    Code:
    foo * bar = new foo();
    DELETE(bar);
    Last edited by ninja9578; January 15th, 2010 at 06:46 PM.

  3. #3
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: question on "delete"

    Quote Originally Posted by ninja9578 View Post
    C++ is not designed to be safe, it's designed to do exactly what you tell it to.
    Not entirely true. That's certainly the philosophy of C; but C++ has embraced a policy emphasizing safety from the start, and enhancements like the STL only take things further in that direction. Lots of stuff is kept "under the hood" to make your code safer.

    That said, the reason why is fairly simple: The delete operator takes a pointer by value. Just like any pointer passed by value, the function can modify what it points to (in this case, an allocated memory block), but it cannot modify the pointer itself in any way visible to the caller.

    Could the language have been written so that delete took the pointer by reference instead? Yeah, probably. But there were reasons why that seemed like a bad idea, I'm sure.

    The safest policy is to design your code so that you never have to call delete. I'm not endorsing memory leaks; but usage of STL containers can reduce most of your need to call "new", and usage of smart pointers can remove your need to explicitly call delete even when you do call new. Together, STL containers and smart pointers will make your code infinitely easier to maintain.

  4. #4
    Join Date
    Jan 2010
    Posts
    2

    Re: question on "delete"

    Quote Originally Posted by Lindley View Post
    Not entirely true. That's certainly the philosophy of C; but C++ has embraced a policy emphasizing safety from the start, and enhancements like the STL only take things further in that direction. Lots of stuff is kept "under the hood" to make your code safer.

    That said, the reason why is fairly simple: The delete operator takes a pointer by value. Just like any pointer passed by value, the function can modify what it points to (in this case, an allocated memory block), but it cannot modify the pointer itself in any way visible to the caller.

    Could the language have been written so that delete took the pointer by reference instead? Yeah, probably. But there were reasons why that seemed like a bad idea, I'm sure.

    The safest policy is to design your code so that you never have to call delete. I'm not endorsing memory leaks; but usage of STL containers can reduce most of your need to call "new", and usage of smart pointers can remove your need to explicitly call delete even when you do call new. Together, STL containers and smart pointers will make your code infinitely easier to maintain.
    Actually in the afternoon I happened to remember that C++ passed p by value...But your comment is very enlightening. Thank you very much.

    P.S. I also thought about this. suppose I happened to define pp = p; then in some place I delete p and set it to 0, but chances are that I will delete pp if I couldn't remember the above definition. In this case, p =0 won't help, I will still get an undefined behavior.

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: question on "delete"

    Yes, aliasing (two pointers directed at the same object) is certainly a problem you need to deal with. The typical solution to that is reference counting, such as is done by the std::tr1::shared_ptr smart pointer class. Only when the reference count reaches 0 does the object finally get destroyed.

  6. #6
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: question on "delete"

    Quote Originally Posted by Lindley View Post
    Not entirely true. That's certainly the philosophy of C; but C++ has embraced a policy emphasizing safety from the start, and enhancements like the STL only take things further in that direction. Lots of stuff is kept "under the hood" to make your code safer.

    That said, the reason why is fairly simple: The delete operator takes a pointer by value. Just like any pointer passed by value, the function can modify what it points to (in this case, an allocated memory block), but it cannot modify the pointer itself in any way visible to the caller.

    Could the language have been written so that delete took the pointer by reference instead? Yeah, probably. But there were reasons why that seemed like a bad idea, I'm sure.

    The safest policy is to design your code so that you never have to call delete. I'm not endorsing memory leaks; but usage of STL containers can reduce most of your need to call "new", and usage of smart pointers can remove your need to explicitly call delete even when you do call new. Together, STL containers and smart pointers will make your code infinitely easier to maintain.
    Good point.
    Thanks for your help.

  7. #7
    Join Date
    May 2009
    Posts
    2,413

    Re: question on "delete"

    Quote Originally Posted by delpi View Post
    I learned that it safe "delete" a 0 (NULL) pointer, but it's undefined behavior to "delete" a pointer twice. So they told me to always add "p=0;" after deleting p.
    The suggested DELETE macro preferably could be complemented with an assert, like

    Code:
    #define DELETE(ptr);\
       {\
           _assert(ptr); // throws if ptr is 0
          delete ptr;\
          ptr = 0;\
       }
    Now you'll get a runtime error in debug mode if ptr is 0. This allows you to fix the bug and not just hide it. Otherwise you're just pouring perfume on a turd.

    Also check out shared_ptr, soon to become part of the C++ standard library. It's a reference counting smart pointer which takes on the responsibility of managing an object's life-time.
    Last edited by nuzzle; January 22nd, 2010 at 06:42 AM.

  8. #8
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

  9. #9
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: question on "delete"

    Quote Originally Posted by delpi View Post
    Here comes my question:
    It seems that we can just add "p=0" into the implementation of the "delete" operator in order to save some typing for coder and it's much safer. But so far it's not the case. So I am wondering why it's not and what's side effect of this addition.
    I would guess that in a big majority of cases (probably >90%) the pointer for which delete is being called will either run out of scope shortly after the delete call, or the object it belongs do will be destroyed (delete called in destructor). Setting a variable just before it is getting deleted is useless code, so your suggestion would introduce useless code in 90% of the cases where the use would be in only 10%.

    If you stick with good design and call delete only in destructor of your objects, you will hardly encounter the double-delete problem.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  10. #10
    Join Date
    Aug 2007
    Posts
    858

    Re: question on "delete"

    Quote Originally Posted by nuzzle View Post
    The suggested DELETE macro preferably could be complemented with an assert, like

    Code:
    #define DELETE(ptr);\
       {\
           _assert(ptr); // throws if ptr is 0
          delete ptr;\
          ptr = 0;\
       }
    Now you'll get a runtime error in debug mode if ptr is 0. This allows you to fix the bug and not just hide it. Otherwise you're just pouring perfume on a turd.
    There's no point in the assert, honestly. Calling delete on a null pointer is a no-op so there's no reason to check for that, and if the pointer has already been deleted but not set back to null, the assert isn't going to catch it.

  11. #11
    Join Date
    May 2009
    Posts
    2,413

    Re: question on "delete"

    Quote Originally Posted by Speedo View Post
    There's no point in the assert, honestly. Calling delete on a null pointer is a no-op so there's no reason to check for that, and if the pointer has already been deleted but not set back to null, the assert isn't going to catch it.
    I've assumed that the DELETE macro is used through-out of course, not just sometimes. Then the assert will raise an exception if a pointer is deleted twice. (and even better, if all pointers are systematically initialized to null it will also raise an exception if a pointer was never assigned an object before it was deleted.)

    So there's every reason in the world to add the assert. It will alarm you about a bug that would otherwise be passed over in silence. Without the assert the DELETE macro is like pouring perfume on a turd. It just removes the bad smell. But with the assert it becomes a tool in helping you to find and remove the actual turd.
    Last edited by nuzzle; January 22nd, 2010 at 10:13 AM.

  12. #12
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: question on "delete"

    Quote Originally Posted by delpi
    It seems that we can just add "p=0" into the implementation of the "delete" operator in order to save some typing for coder and it's much safer. But so far it's not the case. So I am wondering why it's not and what's side effect of this addition.
    Richard.J linked to an article where Stroustrup answers your question by answering the FAQ: Why doesn't delete zero out its operand? That same article provides an example of a destroy function template that is perhaps a better alternative to ninja9578's DELETE macro example.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured