473,398 Members | 2,125 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

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

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"?

Nov 3 '05 #1
13 3068
>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.

Nov 3 '05 #2

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

Nov 3 '05 #3
gary <zw**@gawab.com> 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_f...ml#delete-zero

--
Marcus Kwok
Nov 3 '05 #4
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
kb******@gascad.at
Nov 3 '05 #5

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.

Nov 3 '05 #6
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 '05 #7
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).
Nov 3 '05 #8
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.

Nov 3 '05 #9
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

Nov 3 '05 #10
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
Nov 3 '05 #11
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
Nov 3 '05 #12
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
Nov 5 '05 #13
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
Nov 5 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Pablo J Royo | last post by:
Hello: i have a function that reads a file as an argument and returns a reference to an object that contains some information obtained from the file: FData &ReadFile(string FilePath); But ,...
6
by: CodeCracker | last post by:
class A { public: A(obj &objRef): mObj(objRef) { } ~A() { delete &mObj; } private: Obj &mObj; }
32
by: Christopher Benson-Manica | last post by:
Is the following code legal, moral, and advisable? #include <iostream> class A { private: int a; public: A() : a(42) {}
13
by: Don Vaillancourt | last post by:
What's going on with Javascript. At the beginning there was the "undefined" value which represented an object which really didn't exist then came the null keyword. But yesterday I stumbled...
6
by: R.Z. | last post by:
i'm using a class from some api that is said to automatically call its destructor when its out of scope and deallocate memory. i create instances of this class using "new" operator. do i have to...
2
by: Jason | last post by:
In C++, I can create an object on the heap and have it kill itself when it's done (i.e. delete this) In .NET, I have a class which triggers a worker thread. When the worker thread is finished,...
5
by: mkaushik | last post by:
Hi everyone, Im just starting out with C++, and am curious to know how "delete <pointer>", knows about the number of memory locations to free. I read somewhere that delete frees up space...
19
by: Daniel Pitts | last post by:
I have std::vector<Base *bases; I'd like to do something like: std::for_each(bases.begin(), bases.end(), operator delete); Is it possible without writing an adapter? Is there a better way? Is...
30
by: Medvedev | last post by:
i see serveral source codes , and i found they almost only use "new" and "delete" keywords to make they object. Why should i do that , and as i know the object is going to be destroy by itself at...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.