How do you tell if a pointer doesn't point to anything...

N

Narf the Mouse

....Without using NULL? There must be a way; people keep talking about
storing pointers to objects in different locations in the program.

Thanks.
 
M

Mike Wahler

Narf the Mouse said:
...Without using NULL?


If your program does not initialize or assign a value
to a pointer, then it doesn't point to anything.
That's how you tell.
There must be a way; people keep talking about
storing pointers to objects in different locations in the program.

That doesn't really have anything to do with
your question.

-Mike
 
N

Narf the Mouse

If your program does not initialize or assign a value
to a pointer, then it doesn't point to anything.
That's how you tell.

At which point it crashes, which isn't what I want.
That doesn't really have anything to do with
your question.

-Mike

Can't I be an optimist on an unrelated tangent?

In other news, if I just make the pointer equal to an object of class
NullObjectClass, then include a 'bool isNull ();' function in all the
classes, I can write the program so that a relatively equivalent thing
will happen. I can even reuse the same type of NullObject for each type
of pointer.

So, if anyone wants to know how to accomplish something along those
lines, that's one way.
 
K

Kai-Uwe Bux

Narf said:
Er...Then what do people do with all those pointers scattered around?

They think through the program and prove for every single line where they
use a pointer that it is valid. That is hard (in fact, it is equivalent to
the halting problem, so you cannot leave this kind of deduction to the
compiler). It gets even harder in the presence of code that might throw
exceptions (since every new has to pair with exactly one delete along each
execution path). All of this being so difficult is one of the main reasons
that pointers are best avoided.


Best

Kai-Uwe Bux
 
I

Ian Collins

Narf said:
Er...Then what do people do with all those pointers scattered around?
What pointers? If you're that concerned, either set them to NULL after
delete or avoid them altogether and use smart pointer objects.
 
K

kwikius

Narf said:
At which point it crashes, which isn't what I want.


Can't I be an optimist on an unrelated tangent?

In other news, if I just make the pointer equal to an object of class
NullObjectClass, then include a 'bool isNull ();' function in all the
classes, I can write the program so that a relatively equivalent thing
will happen. I can even reuse the same type of NullObject for each type
of pointer.

You can do that but you presumably need a way to remember what type of
object it points to. You could also wrap your pointer in some class and
keep the raw pointer private, but what you end up with looks quite
similar to a smart pointer:

This one is pretty good and is destined to become part of the C++
standard:

http://www.boost.org/libs/smart_ptr/shared_ptr.htm

It manages the raw pointers life and deletes it when the last reference
is destroyed. Can also be checked for null. Also takes care of
downcasting and dynamic up casting and so on.

regards
Andy Little
 
J

Jim Langston

Kai-Uwe Bux said:
They think through the program and prove for every single line where they
use a pointer that it is valid. That is hard (in fact, it is equivalent to
the halting problem, so you cannot leave this kind of deduction to the
compiler). It gets even harder in the presence of code that might throw
exceptions (since every new has to pair with exactly one delete along each
execution path). All of this being so difficult is one of the main reasons
that pointers are best avoided.

Actually, I find it just as hard as ensuring my integer variables have valid
data. If you think about what you're doing, it's not necessarily as hard as
anything else.

Just make sure a couple of things and you'll be fine.
1. When you create a pointer, intialize it. Either to NULL to some valid
location.
2. When you change a pointer, think about what it was pointing to before, is
it now a dangling pointer (nothing pointing to it) so has to be deleted? Or
something else?
3. When you're done using a pointer either delete it or assign it to NULL.

Most of the cases I deal with pointers are for containers of polymorphic
objects. It's usually very simple in that case, I new it and push it onto
the container.

When ever I remove it from a contaer, I delete it.

When I"im doing with a container I iteratre though it and delete all the
pointers.

For this I find I hardly ever have problems with my pointers pointing to
invalid data.
 
W

Wayne Marsh

Jim said:
Actually, I find it just as hard as ensuring my integer variables have valid
data. If you think about what you're doing, it's not necessarily as hard as
anything else.

Except that you don't have to worry about cleaning up an integer.
Everything is nice and automatic.

Of course, more robust code would probably be using the RAII paradigm.
 
D

David Harmon

On 25 Nov 2006 23:31:06 -0800 in comp.lang.c++, "Narf the Mouse"
At which point it crashes, which isn't what I want.

No, it doesn't crash unless you try to _access_ that pointer value
somehow, either to examine it or to use it. Which you DO NOT do,
because that would be wrong.

Seriously, don't write your code in such a way as to have invalid
pointers littered around all over, and avoid the problem before it
happens. You probably shouldn't be using very many raw pointers anyway.
What are you trying to accomplish?
 
K

Kai-Uwe Bux

Jim said:
Actually, I find it just as hard as ensuring my integer variables have
valid
data. If you think about what you're doing, it's not necessarily as hard
as anything else.

Just make sure a couple of things and you'll be fine.
1. When you create a pointer, intialize it. Either to NULL to some valid
location.
2. When you change a pointer, think about what it was pointing to before,
is
it now a dangling pointer (nothing pointing to it) so has to be deleted?
Or something else?
3. When you're done using a pointer either delete it or assign it to NULL.

I beg to differ. The pitfalls are plenty and sometimes subtle. Consider the
seemingly simple case of just one pointer pointing to one pointee:

template < typename T >
class X {
T * ptr;
public:

X ( T const & t )
: ptr ( new T ( t ) )
{}

~X ( void ) {
delete ptr;
}

// copy constructor and assignment operator omitted (they would distract).
// BEWARE: the compiler generated ones, would be bad !!!
};

versus:

template < typename T >
class X {
T * ptr;
public:

X ( T const & t )
: ptr ( new T )
{
*ptr = t;
}

~X ( void ) {
delete ptr;
}

// copy constructor and assignment operator omitted (they would distract).
// BEWARE: the compiler generated ones, would be bad !!!
};

The second version is buggy (it might leak). It does, however, not violate
any of your rules.

Most of the cases I deal with pointers are for containers of polymorphic
objects. It's usually very simple in that case, I new it and push it onto
the container.

When ever I remove it from a contaer, I delete it.

I take it, you never copy those containers around? The more serious
problems, of course, start when you have multiple pointers pointing to the
same pointee. That's what I usually run into when I write custom
containers.

When I"im doing with a container I iteratre though it and delete all the
pointers.

For this I find I hardly ever have problems with my pointers pointing to
invalid data.

Lucky you.


Best

Kai-Uwe Bux
 
F

Frederick Gotham

Narf the Mouse:
...Without using NULL? There must be a way; people keep talking about
storing pointers to objects in different locations in the program.


Forgetting for the moment that you come across as a troll, you can rely on
conversion to "bool" to determine whether a pointer has the null pointer
value. This conversion may be implicit, or you may force it with a cast:

bool x = p; /* Implicit */

if (p) /* Implicit */
{

}
 
M

Mike Wahler

Frederick Gotham said:
Narf the Mouse:



Forgetting for the moment that you come across as a troll, you can rely on
conversion to "bool" to determine whether a pointer has the null pointer
value.

Not one which has never been initialized or assigned.
I think that's what OP is asking about.
This conversion may be implicit, or you may force it with a cast:

bool x = p; /* Implicit */

if (p) /* Implicit */
{

}

{
int *p;

if(p) /* UB */
;
}

-Mike
 
F

Frederick Gotham

Mike Wahler:
Not one which has never been initialized or assigned.
I think that's what OP is asking about.


Okey dokey, start from the basics:

If you don't initialise an object of intrinsic type, then it contains
garbage. Sometimes it may contain a random, yet valid, value. Other times,
it may contain a value which will cause chaos when you try to interpret it
(this is known as trapping).

Neglecting to initialise a pointer variable is exactly the same as
neglecting to initialise an int, or a double, or a bool. It has an
indeterminant value. The value it contains may be null, or it may be a
random yet valid value, or it may be a random and invalid value.

If a pointer did not get its value through legitimate means, then you can't
expect it to do anything for you. You can't expect it to tell you whether
it's null. You can't expect it to tell you whether it points to an actual
object.

So to answer the question: The C++ Standard provides no means by which to
confirm the validity or nullness of a misused pointer. If you want such a
safety net, then write a class:

class Ptr {
public:

bool IsValid() const { ... }
}

, just don't expect any proficient programmer to agree with you.
 
D

David Harmon

On Sun, 26 Nov 2006 16:36:07 GMT in comp.lang.c++, "Mike Wahler"
Not one which has never been initialized or assigned.
I think that's what OP is asking about.

Based on "storing pointers to objects in different locations in the
program" Narf seems to be concerned about the situation where an object
is allocated, pointers to it get proliferated throughout his plate of
spaghetti, and then he deletes the object leaving nasty invalid pointers
scattered all over like land mines after a communist war. (Please
pardon the sloppy analogy.) The first and best answer to that is "don't
do that."

But another answer is, if you want a particular behavior then use a
class that is written to have that behavior. Use shared_ptr and
weak_ptr (tr1:: or boost::). Shared pointers stay valid as long as long
as you keep a copy, and you can validly test a weak pointer to see if it
still points to a valid object. Don't use raw pointers where you need
more than what raw pointers do.
 
D

Daniel T.

Narf the Mouse said:
...Without using NULL? There must be a way; people keep talking about
storing pointers to objects in different locations in the program.

Obviously, if you don't point it to anything, then it doesn't point to
anything, if you point it to something, then delete that something, then
it doesn't point to anything.

Why is this such a hard concept for you?
 
D

Dino

Daniel said:
Obviously, if you don't point it to anything, then it doesn't point to
anything, if you point it to something, then delete that something, then
it doesn't point to anything.

Why is this such a hard concept for you?

Visit www.boot.org and take a look at their smart pointer library. I
think this is what you are looking for. One of the other posts
referred to it as well.

It uses the proxy design pattern to create an object that owns the
pointer, so you are not required to perform ubiquitous error prone
silly NULL checks. Hopefully, the C++ committee will wise up and make
this part of the standard. You may have also heard of smart pointers,
as "reference counted" pointers. You could also find reference to this
in Coplien's Advanced C++.

Cheers,
D.
 
N

Narf the Mouse

...Without using NULL? There must be a way; people keep talking about
storing pointers to objects in different locations in the program.

Thanks.

Thanks for the many replies; too many to reply to individually, so...

Thanks to everyone who pointed (Pun not intended) me towards smart
pointers; having taught myself c++, my knowledge is rather spotty and I
didn't know about them. Shared_ptr seems to be exactly what I was
looking for.

As for what I'm trying to do, I'm currently on the third re-write of my
roguelike and the code does not resemble spaghetti code. I asked this
question because the functionality I was looking for, or something like
it, would allow me to store all line of sight results in the map itself
by simply storing a pointer to each character that could see that map
square. Then, if the CharacterClass had to know if it could see a
square, all it would have to do is compare the stored pointers to the
'this' value.

I believe that also answers those who were unkind enough to call me a
troll, and a lot more politely.
 
D

David Harmon

On 27 Nov 2006 09:54:51 -0800 in comp.lang.c++, "Narf the Mouse"
As for what I'm trying to do, I'm currently on the third re-write of my
roguelike and the code does not resemble spaghetti code. I asked this

Spaghetti code is one thing, but whenever you start throwing pointers
around you also have to beware of creating spaghetti data structures.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top