Avoiding dangling pointers.

R

Rafael Anschau

I read that you should assign null (0) to all pointers that you call
delete on.

Does that mean:

*p=0(set the value pointed to to 0).

or

p=0(set the address held to zero).

The last one is awkward for none would want a pointer pointing
to address zero(even though it compiles fine, you can´t assign
anything to it).

I find the first still awkward because you are assigning a value to a
place
you no longer use.

Thanks

Rafael
 
C

Christopher

I read that you should assign null (0) to all pointers that you call
delete on.

Does that mean:

*p=0(set the value pointed to to 0).

or

p=0(set the address held to zero).

The last one is awkward for none would want a pointer pointing
to address zero(even though it compiles fine, you can´t assign
anything to it).

I find the first still awkward because you are assigning a value to a
place
you no longer use.

Thanks

Rafael

The latter is pretty standard. You should always check if a pointer is
valid (not pointing to zero) before using it, and be sure to have it
set to zero when it is invalid (after releasing the memory it pointed
to).
 
D

Default User

Rafael said:
I read that you should assign null (0) to all pointers that you call
delete on.

Controversial, at best. I never do that.
Does that mean:

*p=0(set the value pointed to to 0).

This would undefined behavior, as you would be deferencing a pointer to
deleted storage.
or

p=0(set the address held to zero).

The last one is awkward for none would want a pointer pointing
to address zero(even though it compiles fine, you can?t assign
anything to it).

You seem confused. You can't dereference it, but you couldn't before.
You can certainly assign something to p. That is:

delete[] p;
p = 0;
p = new int[20]; // p is int* for this example

Is perfectly fine.
I find the first still awkward because you are assigning a value to
place
you no longer use.

Far more than awkward, it's undefined behavior. You must not do that.




Brian
 
R

Rafael Anschau

If you set p=0, you are pointing nowhere, and I found that weird. But
it actualy makes sense, it´s better to have the program crash
right away if something tries to write on it, than to have it write
fine
on some dark zone of heapland which you will never be able to reach
again.
Reduces debugging time.

Thanks folks.


Rafael said:
I read that you should assign null (0) to all pointers that you call
delete on.

Controversial, at best. I never do that.
Does that mean:
*p=0(set the value pointed to to 0).

This would undefined behavior, as you would be deferencing a pointer to
deleted storage.
p=0(set the address held to zero).
The last one is awkward for none would want a pointer pointing
to address zero(even though it compiles fine, you can?t assign
anything to it).

You seem confused. You can't dereference it, but you couldn't before.
You can certainly assign something to p. That is:

delete[] p;
p = 0;
p = new int[20]; // p is int* for this example

Is perfectly fine.
I find the first still awkward because you are assigning a value to
place
you no longer use.

Far more than awkward, it's undefined behavior. You must not do that.

Brian
 
J

James Kanze

I read that you should assign null (0) to all pointers that you call
delete on.

I'd suggest you throw out whatever book said something as stupid
as that. I almost never set pointers to null after delete, and
I don't know of any good programmers that do.
Does that mean:
*p=0(set the value pointed to to 0).

After a delete, that would be undefined behavior. Of the worst
kind, since it will almost always work. (The most frequent
result of undefined behavior is for it to work in all of your
tests, and then cause a program crash during the important demo
in front of your most important client.)
p=0(set the address held to zero).
The last one is awkward for none would want a pointer pointing
to address zero(even though it compiles fine, you can´t assign
anything to it).

You're not making the pointer point to the address zero here
(despite appearances). You're making it point to nowhere, but
with a testable and copiable value. It's useful in the rare
cases where you have a pointer which sometimes will point to
something, and othertimes won't. When it doesn't point to
something, you set it to null (which you can write NULL or 0).

This is often used in lazy evaluation (the pointer is
initialized to null; at each use, you test for null, and
evalutate it to the usable value if it is null), or for various
caching schemes (in which case, you do set the pointer to null
after a delete, since that's how you recognize that the cache is
invalid). Most deletes, however, occur in destructors, in which
case, there's no sense in setting the pointer to null, since you
can't use it later anyway.
I find the first still awkward because you are assigning a
value to a place you no longer use.

The first is undefined behavior. Don't do it. The second has
some specialized uses, but there's certainly no reason to do it
systematically after a delete.
 
J

James Kanze

Ummm, no. You read that you should assign NULL (not "null",
whatever that is) to pointers WHICH HAVE BEEN DELETED.

He probably means a null pointer. A null pointer constant
(any integral constant expression evaluating to 0, but anything
but 0 or NULL would be very strange) will be converted to a null
pointer in pointer contexts.

And of course, there's absolutely no reason to set a pointer to
null after delete, except in a few special cases.
Systematically doing so is generally a sign that the programmer
doesn't really understand what he is doing.
That's not at all the same as what you said.
No. That assigns 0 to the thing being pointed to, not the
pointer. If this is immediately BEFORE calling delete, it's
harmless, but accomplishes nothing.

Actually, of course, in a lot of cases, before or after, it
won't compile. You can't necessarily assign 0 to most types.
If this is AFTER calling delete, it's an illegal memory
access, and may crash your program or your OS.

But probably not during your tests. Only during the demo before
the important client:).
Yes. Do this immediately after delete'ing any pointer.
Why?

I prefer "p=NULL;", myself. "NULL" is usually typedefed
in the compiler's headers to "(void*)0" or "0".

In C++, it must be a typedef to a "null pointer constant".
Which despite the name, may not have pointer type---it must be
an integral type. "0" is by far the most frequent, although
I've also seen "0L", and something like "(1/2)" would be legal.
"(void*)0" is not legal.
I use it because it makes it visually clear that a pointer is
being invalidated.

I'd say that "delete" makes it pretty clear already. If the
programmer doesn't know that delete invalidates the pointer, I'd
say that that's a problem in itself.
Why not???

Well, you might want it on some embedded systems. But assigning
a constant 0 to a pointer does NOT make it point to the address
zero. It makes it point nowhere.
*ALL* pointers should be set to 0 when not in use!

More to the point, you shouldn't keep pointers not in use
around.
Then before using them, always test them to
make sure they're not NULL:
if (NULL != pAardvark)
{
*pAardvark = 37.94;
}

And what does this buy you (except obfuscation)? Just because a
pointer isn't null doesn't mean that it points to something
valid.
 
J

James Kanze

Controversial, at best. I never do that.
This would undefined behavior, as you would be deferencing a
pointer to deleted storage.

It just occurred to me, but...

How often do you have pointers to a numerical type anyway?
Cases where this would even compile shouldn't be that frequent.

For the rest, I totally agree with you.
 
K

Krice

I read that you should assign null (0) to all pointers that you call
delete on.

There is no reason to do that. What you should do is keep track
of created objects. That can be made easier with containers
which own the objects and handle the destruction once the object
is no longer needed.
Or in case of global objects just delete the object in program
exit and that should do the trick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,175
Messages
2,570,947
Members
47,498
Latest member
yelene6679

Latest Threads

Top