Why compilers do not "p = NULL" automatically after programs do "delete p"?

Discussion in 'C++' started by gary, Nov 3, 2005.

  1. gary

    gary Guest

    Hi,
    We all know the below codes are dangerous:
    {
    int *p = new int;
    delete p;
    delete p;
    }
    And we also know the compilers do not delete p if p==NULL.

    So why compilers do not "p = NULL" automatically after programs do "delete p"?
     
    gary, Nov 3, 2005
    #1
    1. Advertising

  2. gary

    Marcus Kwok Guest

    gary <> wrote:
    > Hi,
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }
    > And we also know the compilers do not delete p if p==NULL.
    >
    > So why compilers do not "p = NULL" automatically after programs do "delete p"?


    Stroustrup answers this in his FAQ:
    http://www.research.att.com/~bs/bs_faq2.html#delete-zero

    --
    Marcus Kwok
     
    Marcus Kwok, Nov 3, 2005
    #2
    1. Advertising

  3. gary

    dragoncoder Guest

    >So why compilers do not "p = NULL" automatically after >programs do "delete p"?

    Because they can't. You will have to pass somehow the address of p to
    set p to NULL. Of course this is just one aspect of it.
     
    dragoncoder, Nov 3, 2005
    #3
  4. gary

    Nan Li Guest

    gary wrote:
    > Hi,
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }
    > And we also know the compilers do not delete p if p==NULL.
    >
    > So why compilers do not "p = NULL" automatically after programs do "delete p"?



    One problem is efficiency. 'p = NULL' at least takes one instruction
    to complete. If you delete a point in a very deep loop, the cost could
    be huge.

    Nan
     
    Nan Li, Nov 3, 2005
    #4
  5. Re: Why compilers do not "p = NULL" automatically after programs do"delete p"?

    gary wrote:
    >
    > Hi,
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }
    > And we also know the compilers do not delete p if p==NULL.
    >
    > So why compilers do not "p = NULL" automatically after programs do "delete p"?


    * Because they don't have to.
    * Because it creates a false sense of security:

    int* p = new int;
    int* q = p;

    delete q; // Assume q gets set to NULL by the compiler ...
    delete q; // ... so this would be fine
    delete p; // But this is not. Just because the compiler set q to NULL
    // it would not do the same with p

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Nov 3, 2005
    #5
  6. gary

    Nan Li Guest

    dragoncoder wrote:
    > >So why compilers do not "p = NULL" automatically after >programs do "delete p"?

    >
    > Because they can't. You will have to pass somehow the address of p to
    > set p to NULL. Of course this is just one aspect of it.


    I think if p is a l-value variable, the compiler is able to assign it
    to NULL( it is almost equal to adding 'p=NULL' after 'delete p'.) But
    if p is something like constant, temporary variable, or const, it
    cannot be modified. So in general, the compiler cannot do that.
     
    Nan Li, Nov 3, 2005
    #6
  7. gary

    Guest

    Hi Gary,

    My thoughts:

    - In "delete <expression>", the expression doesn't have to be
    assignable to - it could be a calculated value, a const value etc.,

    - Seems to be a case of Design-by- Contract-like philosophy, where a
    facility doesn't presume to do something which may be unnecessary just
    to alleviate a programmatic error. This philosophy sometimes
    incorporates an argument such as "if we guarantee the second delete is
    correct, then programmers lose the likelihood that their program
    SIGSEGVs (or equiv), which means they're less likely to realise they
    need to correct their code". DbC's basically a load of crap, but I've
    heard such arguments.

    - Code size and performance. In the dark old days, people genuinely
    cared about a few extra bytes for an extra instruction, and a few extra
    clock cycles. Though in the last 20 years my home computer's gone from
    3.375kHz and 32kb RAM to 2.8GHz and 1GB RAM, not all systems are
    grunty, and a few programmers still care.

    - More generally, there's an attitude of "do the minimum, and let the
    safety-conscious choose what else they'd like to do". Is a simple
    assignment of 0 really enough to satisfy you? You don't want a checked
    allocation system that throws or aborts on error? C++ lets you write
    and use your own allocation routines which reflect your own concerns.

    Cheers,

    Tony
     
    , Nov 3, 2005
    #7
  8. gary

    Ron Natalie Guest

    Re: Why compilers do not "p = NULL" automatically after programsdo "delete p"?

    gary wrote:
    > Hi,
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }
    > And we also know the compilers do not delete p if p==NULL.
    >
    > So why compilers do not "p = NULL" automatically after programs do "delete p"?
    >

    The argument to delete is an rvalue. Delete wouldn't necessarily be
    able to change it even if it wanted to.

    Further, it only fixes the problem in trivial cases (i.e., when the
    pointer value isn't stored in multiple locations).
     
    Ron Natalie, Nov 3, 2005
    #8
  9. gary

    Kaz Kylheku Guest

    gary wrote:
    > Hi,
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }


    That is only a textbook example illustrating a double delete. What is
    dangerous in the real world are all kinds of hard-to-find bugs that
    don't stand out like the above contrived example.

    Also, note that /any use whatsoever/ of the value of p after the first
    delete p expression is undefined. Not just double deletes. Even
    comparing p to another pointer is undefined behavior.

    > So why compilers do not "p = NULL" automatically after programs do "delete p"?


    Because that would not achieve any benefit for actual programs which
    are not textbook examples.

    The real problem is that the program may have copies of the pointer in
    variables other than just p. These pointers may be hidden throughout
    the network of live object's in that program's run-time space.

    Assigning NULL to p won't do anything about these other copies.

    One such trivial scenario is when deletion is wrapped behind a
    function:

    void ObjectFactory::Destroy(Object *x)
    {
    delete x;
    }

    Assigning NULL to x here won't do anything useful, because the scope is
    ending. The caller can still write:

    factory->Destroy(obj);
    factory->Destroy(obj);

    Both x and obj are copies of the same pointer; assigning to local
    variable x does nothing about obj still having a copy of that now
    invalid value.

    Also, the argument to delete might not be a modifiable lvalue.

    int *const ptr = new int[10];

    delete ptr;

    ptr = 0; // error, it's a const!

    The argument to delete might contain conversions so that it's not an
    lvalue:

    // p is a (void *), but we know it points to an object of SomeClass

    delete (SomeClass *) p;

    ((SomeClass *) p) = 0; // error, assignment to non-lvalue

    Lastly, consider that delete can be a user-defined operator. If it
    performed this type of assignment in some conditions, would
    user-defined allocators override it?

    The delete operator shouldn't be regarded as a deallocating function
    but as an annotation which says "the object referenced by this pointer
    won't be touched by the program any longer". If the delete operator has
    no effect on the value of a variable, then we can ignore the annotation
    and use an alternate means of computing the object lifetimes.

    Suppose that the we replace the global delete operator with one that
    does nothing, and add a garbage collector underneath. We suspect that
    the program contains bugs, such as uses of objects that have been
    deleted, and multiple deletes. But these problems are ironed out with
    the garbage collector. The assigning delete would interfere with this
    solution. It would leave the suspicion that some pointers that are
    overwritten with null by delete will be dereferenced.
     
    Kaz Kylheku, Nov 3, 2005
    #9
  10. gary

    savagesmc Guest

    You should check out what are called "smart pointers". For example the
    STL has std::auto_ptr<>, and the boost library has 4 or 5 different
    types of smart pointers that are each useful in a specific scenario.

    Those smart pointers are the standard way of wrapping naked pointers in
    a safe & correct manner.

    I know that some of the boost smart pointers are going to be adopted in
    the next version of the c++ standard, so that should tell you something
    about how important and relevant they are.

    Check them out.

    Steve
     
    savagesmc, Nov 3, 2005
    #10
  11. gary

    Mike Smith Guest

    Re: Why compilers do not "p = NULL" automatically after programsdo "delete p"?

    gary wrote:
    > Hi,
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }
    > And we also know the compilers do not delete p if p==NULL.


    p certainly is deleted if it == NULL. However, the C++ Standards
    defines the deleting of NULL as having no effect.

    --
    Mike Smith
     
    Mike Smith, Nov 3, 2005
    #11
  12. Re: Why compilers do not "p = NULL" automatically after programsdo "delete p"?

    gary wrote:
    > We all know the below codes are dangerous:
    > {
    > int *p = new int;
    > delete p;
    > delete p;
    > }
    > And we also know the compilers do not delete p if p==NULL.
    >
    > So why compilers do not "p = NULL" automatically after programs do "delete p"?
    > ...


    Because it wouldn't really achieve anything. In the real life the problem you
    were trying to describe by the above example usually looks as follows

    int* p1 = new int;
    int* p2 = p1;

    delete p1;
    delete p2;

    Setting one pointer to null won't help at all.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 3, 2005
    #12
  13. gary

    Calum Grant Guest

    Re: Why compilers do not "p = NULL" automatically after programsdo "delete p"?

    Nan Li wrote:
    > gary wrote:
    >
    >>Hi,
    >> We all know the below codes are dangerous:
    >> {
    >> int *p = new int;
    >> delete p;
    >> delete p;
    >> }
    >> And we also know the compilers do not delete p if p==NULL.
    >>
    >> So why compilers do not "p = NULL" automatically after programs do "delete p"?

    >
    >
    >
    > One problem is efficiency. 'p = NULL' at least takes one instruction
    > to complete. If you delete a point in a very deep loop, the cost could
    > be huge.


    Very true. But isn't this a case of over-optimization? I mean, the
    number of CPU cycles in the memory allocator will be much greater than
    the effort to set p=0.

    I think for normal application code, pointers are best avoided. It's
    much better to use iterators, containers and smart pointers, since then
    all these problems are taken care of.

    Calum
     
    Calum Grant, Nov 4, 2005
    #13
  14. gary wrote:

    > So why compilers do not "p = NULL" automatically after programs do "delete
    > p"?


    Several reasons:

    p can be const, can be an expression...

    Many times p will go out of scope just after delete, no need to modify it.

    If you want to always assign NULL to a pointer being delete'd, you can
    esaily write a template function that do both things.

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Nov 5, 2005
    #14
    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. Replies:
    5
    Views:
    26,737
    Mike Schilling
    Mar 29, 2006
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    917
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,033
    Smokey Grindel
    Dec 2, 2006
  4. geletine

    commercial c compilers vs free c compilers

    geletine, Jul 2, 2006, in forum: C Programming
    Replies:
    33
    Views:
    1,328
  5. lostlander
    Replies:
    5
    Views:
    417
    Keith Thompson
    Dec 10, 2007
Loading...

Share This Page