validity of a pointer

S

sinbad

finding the validity of the address pointed to by a pointer,
how this can be done.

a pointer "ptr" having a value of 0x808 is obviosuly not a
valid value. At the same time a value of 0xffffffff or 0x0000000
is inavalid and if a process address space is inbetween x and y;
any pointer value "< x" or "> y" would be invalid.
Is it possible to write this kind of checking in c
under linux platform.

thanks
 
W

Wolfgang Draxinger

sinbad said:
a pointer "ptr" having a value of 0x808 is obviosuly not a
valid value.

Say's who?
At the same time a value of 0xffffffff or
0x0000000 is inavalid and if a process address space is
inbetween x and y; any pointer value "< x" or "> y" would be
invalid.

First read the pointer FAQ. Then you must understand, that the
only "invalid" pointer in terms of C is the null pointer, with
the value 0.

Any terms of additional validity/invalidity are imposed by the
operating system, so you've to check through this.
Is it possible to write this kind of checking in c
under linux platform.

Sure. Open '/proc/self/maps'. It tells you exactly the memory
layout of the process. Read accessing any of the shown ranges
will expose well defined behaviour. In the maped areas with
write access you can also write without causing a SIGSEGV, but I
strongly discourage it, as it will probably corrupt vital
process data, especially if you write to the uppermost addresses
of the '[stack]' mapping.

Wolfgang
 
J

James Kuyper

sinbad said:
finding the validity of the address pointed to by a pointer,
how this can be done.

a pointer "ptr" having a value of 0x808 is obviosuly not a
valid value. At the same time a value of 0xffffffff or 0x0000000
is inavalid and if a process address space is inbetween x and y;
any pointer value "< x" or "> y" would be invalid.
Is it possible to write this kind of checking in c
under linux platform.

The range of valid addresses is implementation-specific. Linux has been
successfully ported to a very wide variety of platforms; I'd be somewhat
surprised if your description of valid pointers were correct on all of
them - though I'm not ruling out that possibility.

The only validity check you can perform in portable code is ptr!=NULL.
For any more comprehensive validity check you need to use
implementation-specific methods. You'll get better responses to such a
question on a newsgroup devoted to your implementation. If there is a
single answer that works on all Linux implementations, then you should
be able to find it on a Linux newsgroup.

The only implementation-specific answers you'll get on this newsgroup
will be from trolls, some of whom will give you incorrect answers out of
incompetence, and one of whom has a history of giving deliberately
incorrect answers, apparently just for the fun of watching people post
messages correcting him.
 
R

Richard

pete said:
An indeterminate pointer is more invalid than a null pointer.

Where are the hosts of people not understanding, while scratching their
beards, what "value 0" means in pointer speak?
 
A

Antoninus Twink

a pointer "ptr" having a value of 0x808 is obviosuly not a valid
value. At the same time a value of 0xffffffff or 0x0000000 is inavalid
and if a process address space is inbetween x and y; any pointer value
"< x" or "> y" would be invalid. Is it possible to write this kind of
checking in c

If a pointer variable contains garbage, then either you didn't
initialize it, or your program is somehow overwriting the memory
locations where the pointer variable is stored.

In either case, you have a bug. The solution is not to try to check at
runtime whether a particular pointer has been clobbered or not, but to
fix the bug.

For the first case, you can use a memory checker tool: an excellent free
one for Linux is valgrind. The checker intercepts calls to malloc() and
free() to keep track of what memory is being allocated where, and alerts
you to reads from uninitialized memory (and also writes outside
allocated memory, and memory leaks).

For the second type of bug, where you overwrite memory you do actually
own, you can fire up your debugger, set a watch at the address of the
pointer variable, and see where it's getting clobbered. Often you'll
find it's an out-by-one error or bounds overflow for a static or
automatic array.
 
N

Nate Eldredge

sinbad said:
finding the validity of the address pointed to by a pointer,
how this can be done.

a pointer "ptr" having a value of 0x808 is obviosuly not a
valid value. At the same time a value of 0xffffffff or 0x0000000
is inavalid and if a process address space is inbetween x and y;
any pointer value "< x" or "> y" would be invalid.
Is it possible to write this kind of checking in c
under linux platform.

This isn't really a good question for comp.lang.c, since it doesn't have
much to do with the C language per se, it's really about Linux.
Crossposted and followups set to comp.os.linux.devel.applications

I think before answering this question, you should think about what you
mean by "valid", and why you want to know whether a pointer is "valid"
or not. What are you going to do with this information?

Other people have mentioned using /proc/self/maps to see if the pointer
points into a region of memory that the process has mapped. Certainly a
pointer that's not in one of these regions isn't very valid, since it
can't point to any object in your program and will cause a segfault if
dereferenced. But even if it is in one of these regions, there's other
reasons it might be pointing to the "wrong" place. Maybe you expect it
to point to an integer containing a number of lines, but it actually
points to the string "Hello world".

Also, regarding /proc/self/maps, doing this check is not very useful,
because what will you do if it fails? Abort the program? If you just
use the pointer, a segfault will do this for you. Clean up first, or
longjmp to some other part of the program? Then put this code in a
SIGSEGV handler. You're really just duplicating a check that the
hardware is already doing.

Sometimes people ask questions like this because they have a function
which takes a pointer as an argument, and, wanting to be careful
defensive programmers, they want to verify the pointer somehow before
they use it. Verifying that arguments make sense is generally a good
idea, but in the case of pointers it isn't really possible. The
function just doesn't know enough about the rest of the program to be
able to check that the calling function is doing what it wants to. In
this case you have to trust the caller. Just use the pointer. If it is
wrong, you'll find out when the program breaks, and that's when you turn
to your debugger to figure out what's going on in the rest of the
program.
 
W

Wolfgang Draxinger

pete said:
An indeterminate pointer is more invalid than a null pointer.

In terms of C a null pointer is not something invalid in the term, that it
may not be there. However dereferencing a null pointer is invalid, thus I
wrote the word "invalid" in quotations marks, to designate it as being
meant in the OPs intention.

Any pointer with a value not being null can be dereferenced legally, as long
as we'te talking in terms of the language.

In terms of a specific implementation there might be further values, that
are invalid for a given pointer type (e.g. pointer values are alignment
constrained).

And then there is the classification of a pointer being valid or not by the
(operating system). Today one can cheaply build a 32 bits machine with 4GiB
memory (costs about 100$). Without a operating system, memory protection
and a paging system the physical memory can be addressed linearily. In this
situation, 32 bit CPU and 4GiB of memory running a single program in
physically addressing mode, virtually every pointer can be dereferenced
without raising a bus error exception.

But the C language deliberately doesn't specify anything about the low level
details that are implied by pointers. The only thing that's granted is,
that a pointer with the value 0 cannot be dereferenced and thus may be
considered invalid.

Wolfgang

P.S.: That I gave some detailed information on how to check a pointer for
validity under Linux is, that there's IMHO no sensible newsgroup for such
questions. The closest match would be comp.os.linux.development.apps, but
the guys there are focused on things like GUI and stuff like that. The
other Linux devel NG is comp.os.linux.development.system, which focuses on
the kernel and there a whole set of other rules apply.
 
K

Keith Thompson

Kaz Kylheku said:
Yes; something invalid is much more invalid that something valid.

A null pointer is invalid for some purposes (i.e., dereferencing). An
indeterminate is invalid for those purposes plus others.
 
W

Wolfgang Draxinger

pete said:
No.
A pointer that points one past an object,
is valid for purposes of pointer arithmetic,
but is not valid for dereferncing.

Yes, but that imposes no constraint on the values a pointer can assume.
Maybe I should have written ...may be dereferenced legally, if its value
points to a object." In special circumstances a object can take up the
entire value range a pointer can assume (except 0 of course). Thus the
language can effetivly imply no _value constraints_ other than '0' on the
validity of dereferencabilty, as in such case a pointer can assume
virtually any value not being 0. However implementations may reserve
certain values as invalid and use those to conserve the behavioue you
pointed out below. Or they simply buffer under-/overrun, which is the usual
case.
Considering three different kinds of operations on a pointer:
1 reading
2 pointer arithmetic
3 dereferencing

An indeterminate pointer is not valid for reading,
nor for pointer arithmetic, nor for dereferencing.

Right, but how do you tell an pointer is definitely indeterminate: You leave
it uninitialized. But then the same rule also applies to any other
uninitialized value, though those will only yield undefined behaviour.
A null pointer is valid for reading;
but not for pointer arithmetic, nor for dereferencing.

A one past pointer is valid for reading.
and for pointer arithmetic.
But not for dereferencing.

A pointer to an object, is valid for reading,
for pointer arithmetic, and also for dereferencing.

....as long as it stays within the bounds of the object.

Wolfgang
 
J

jameskuyper

Wolfgang Draxinger wrote:
....
Any pointer with a value not being null can be dereferenced legally, as long
as we'te talking in terms of the language.

Not if it points one past the end of an array.

Not if the value of the pointer is indeterminate. To be more specific:
Not if it points at an object whose lifetime is ended.
In particular, not if it points at dynamically allocated
memory which has since been free()d.
Not if it it's a FILE* for a stream that has been fclose()d.
 
W

Wolfgang Draxinger

Keith said:
A null pointer is invalid for some purposes (i.e.,
dereferencing). An indeterminate is invalid for those purposes
plus others.

Which still remains the question: How does one determine if a
pointer is indetermined. You can't do it by it's value using
solely the functionality provided by C.

Okay, because some people seem to have misunderstood me another
branch of this thread: I didn't say, that there aren't other
invalidities like null pointers. I just wanted to point out,
that any value one finds in a pointer, except 0, should be
considered possibly valid. And on certain implementations
virtually any pointer value (except 0) could be valid, though
not neccesarily dereferencable, like the value of a pointer
pointing just one element beyond the bounds of an array.

Wolfgang
 
J

jameskuyper

Wolfgang said:
Which still remains the question: How does one determine if a
pointer is indetermined. You can't do it by it's value using
solely the functionality provided by C.

No, the only thing you can do is examine your code for possible causes
of indeterminacy. If the pointer comes in from outside your code, such
checks will, unfortunately, be inadequate.
Okay, because some people seem to have misunderstood me another
branch of this thread: I didn't say, that there aren't other
invalidities like null pointers. I just wanted to point out,
that any value one finds in a pointer, except 0, should be
considered possibly valid.

You should only consider it possibly valid if you've made sure that
your own code has gone out of it's way, if necessary, to ensure that
none of the situations that can render a pointer value indeterminate
have occurred to this pointer value. If your code is linked to other
people's code, the best you can do is hope that they have been equally
careful, but that's not the same as always considering that any non-
null pointer is valid.
 
K

Keith Thompson

Wolfgang Draxinger said:
Which still remains the question: How does one determine if a
pointer is indetermined.
Right.

You can't do it by it's value using
solely the functionality provided by C.

And there's your answer. There *might* be a system-specific way to
determine whether a pointer is "valid", for whatever meaning of the
word "valid" you'd like to apply -- or there might not.
Okay, because some people seem to have misunderstood me another
branch of this thread: I didn't say, that there aren't other
invalidities like null pointers. I just wanted to point out,
that any value one finds in a pointer, except 0, should be
considered possibly valid. And on certain implementations
virtually any pointer value (except 0) could be valid, though
not neccesarily dereferencable, like the value of a pointer
pointing just one element beyond the bounds of an array.

Sure, any non-null pointer value *could* be valid, in the sense that
it might point to an object within your program. But even if you
could test for that, it's really not enough. The important question
is whether the pointer value is correct; does it point to the *right*
object? That's a question that depends intimately on your program
logic.
 
C

CBFalconer

Wolfgang said:
Which still remains the question: How does one determine if a
pointer is indetermined. You can't do it by it's value using
solely the functionality provided by C.

Okay, because some people seem to have misunderstood me another
branch of this thread: I didn't say, that there aren't other
invalidities like null pointers. I just wanted to point out,
that any value one finds in a pointer, except 0, should be
considered possibly valid. And on certain implementations
virtually any pointer value (except 0) could be valid, though
not neccesarily dereferencable, like the value of a pointer
pointing just one element beyond the bounds of an array.

I sometimes form a specific pointer for the purpose of having a
NULL equivalent that is distinguishable from NULL. There is an
example in my hashlib package, used to keep track of deleted
entries, which cannot be replaced with a NULL pointer.
 
S

Stephen Sprunk

Wolfgang said:
Which still remains the question: How does one determine if a
pointer is indetermined. You can't do it by it's value using
solely the functionality provided by C.

Okay, because some people seem to have misunderstood me another
branch of this thread: I didn't say, that there aren't other
invalidities like null pointers. I just wanted to point out,
that any value one finds in a pointer, except 0, should be
considered possibly valid. And on certain implementations
virtually any pointer value (except 0) could be valid, though
not neccesarily dereferencable, like the value of a pointer
pointing just one element beyond the bounds of an array.

There exist some systems where zero is a "valid" pointer, e.g. in MS DOS
it's a pointer to the interrupt vector table.

There is no portable way to test for "indeterminate" pointers, and even
if your OS provides a non-portable function to perform a test,
technically calling it can invoke UB because an argument must be
evaluated to be passed, and examining an indeterminate pointer (not just
dereferencing it) causes UB...

S
 
N

Nate Eldredge

Stephen Sprunk said:
There is no portable way to test for "indeterminate" pointers, and
even if your OS provides a non-portable function to perform a test,
technically calling it can invoke UB because an argument must be
evaluated to be passed, and examining an indeterminate pointer (not
just dereferencing it) causes UB...

Presumably such a system would define the undefined behavior
appropriately. For example, it might document that there are no trap
representations for pointer types (which is commonly the case anyway).
 
K

Kaz Kylheku

Presumably such a system would define the undefined behavior
appropriately.

Not in a way that can magically reach back into the standard language
and make it defined there. :)

It would be ``defined in this dialect of C'', not
``defined in standard C''.
 
N

Nate Eldredge

Kaz Kylheku said:
Not in a way that can magically reach back into the standard language
and make it defined there. :)

It would be ``defined in this dialect of C'', not
``defined in standard C''.

Yes. But standard C also doesn't provide an `is_valid_pointer'
function. So any implementation that did the latter could (should) also
do the former. Of course a program using these features would cease to
be portable standard C.
 

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,266
Messages
2,571,079
Members
48,772
Latest member
Backspace Studios

Latest Threads

Top