Null pointers

J

junky_fellow

Can 0x0 be a valid virtual address in the address space
of an application ?
If it is valid, then the location pointed by a NULL pointer
is also valid and application should not receive "SIGSEGV"
( i am talking of unix machine ) while trying to read that
location.
Then how can i distinguish between a NULL pointer and an invalid
location ?
Is this essential that NULL pointer should not point to any of
the location in the virtual address space ?

If NULL pointer should not essentially point to an invalid
location, then why we should always use NULL to be location 0x0,
can we use some other location as well ?

Is this necessary that whenever an application try to access
location pointed by NULL pointer, it should be aborted by kernel
by posting some signal ?

Please i need your help, beacuse i am getting more confused
as i am reading more and more documents on NULL pointers.
thanx for any help in advance.....
 
C

Chris Dollin

junky_fellow said:
Can 0x0 be a valid virtual address in the address space
of an application ?
Yes.

If it is valid, then the location pointed by a NULL pointer
is also valid and application should not receive "SIGSEGV"
( i am talking of unix machine ) while trying to read that
location.

No. If 0 is a valid (C-accessible) address on the machine, then
0 is not a legal representation for a pointer value.
Then how can i distinguish between a NULL pointer and an invalid
location ?

The null (not NULL) pointer tests equal to a integer constant
expression with value 0. Invalid locations don't.
Is this essential that NULL pointer should not point to any of
the location in the virtual address space ?

It's essential that the null (not NULL) pointer not point to
any C-accessible location.
If NULL pointer should not essentially point to an invalid
location, then why we should always use NULL to be location 0x0,
can we use some other location as well ?

NULL has nothing to do with location 0 (except by coincidence on
most machines). You're confusing the internal representation of
the null pointer with the internal representation of the integer
0 - and the implementation is free to use some *other* representaion
of the null pointer, such as the address of some byte in the run-time
system that no C program can legally see.
Is this necessary that whenever an application try to access
location pointed by NULL pointer, it should be aborted by kernel
by posting some signal ?

No. That's nice, but it's not required.
Please i need your help, beacuse i am getting more confused
as i am reading more and more documents on NULL pointers.
thanx for any help in advance.....

Don't try and understand what's implemented; try and understand
the rules.
 
R

Richard Tobin

junky_fellow said:
Can 0x0 be a valid virtual address in the address space
of an application ?

Historically, and in almost all C implementations, null pointers are
just pointers corresponding to the address 0. In these
implementations, if you put the integer zero into a location whose
size is the same as a pointer, and then treat that location as a
pointer, you will be doing exactly the same thing as if you had a real
null pointer.

The C standards don't require things to work like that though. They
make null pointers more abstract, like nil in Lisp or null in Java.
Null pointers *could* be represented so that they corresponded to the
address 0x12345678. In that case, the implementation would have to be
careful never to put a real object at address 0x12345678, and an
assignment like "int *foo = 0" or "int *foo = NULL" would have to be
compile to code that put the value 0x12345678 into foo's location.
Setting the location to zero by some means such as memset or calloc
would not work.

All this is quite separate from whether dereferencing a null pointer
causes some kind of exception. On modern machines with virtual memory
it's usual to unmap that page containing the null pointer address
(which in practice is page 0 - an implementation that represented null
pointers as 0x12345678 could unmap that page instead). This wasn't
always the case: a lot of early Vax C code assumed that null pointers
pointed to a byte containing zero, so that null pointers and empty
strings were interchangable. This practice was eradicated once people
ported their programs to machines like the early Suns, which did unmap
page 0.

-- Richard
 
J

Joona I Palaste

No. Zero is never a valid location in C.

It's not a valid pointer value, but it can be a valid memory address. As
has been stated, pointer values need not correspond exactly to memory
addresses.
 
K

Keith Thompson

Chris Dollin said:
No. If 0 is a valid (C-accessible) address on the machine, then
0 is not a legal representation for a pointer value.

It depends on what you mean by "valid".

(I'm going to use the term "all-bits-zero" to refer to memory address
zero, since a literal 0 can refer to some other address.)

If an implementation's representation of a null pointer is
all-bits-zero, no C object (either declared or allocated via malloc())
can exist at that address. Any attempt to dereference a null pointer
invokes undefined behavior. However, it's entirely possible (for a
given implementation) that there is an addressible memory location at
address all-bits-zero, and that a C program is able to access it
by dereferencing a null pointer.

Dereferencing a null pointer invokes undefined behavior; that can
include fetching a value stored at address all-bits-zero, trapping, or
making demons fly out your nose.

An implementation is obliged not to store a visible C object at the
address it reserves for null pointers; it's not obliged to trap
attempts to dereference a null pointer.

(Actually that's not quite true; there could be a visible object
named, say, __FOO__ at the null address, perhaps wit the specific
purpose of preventing any other object from occupying that address.
I don't know of any implementation that actually does this.)

To the OP: read sections 4 and 5 of the C FAQ if you haven't already.
 
O

Old Wolf

Mabden said:
No. Zero is never a valid location in C.

Chapter and verse? AFAIK there are several architectures where
zero is a valid location, and you can safely read and write from it.
 
G

Gordon Burditt

Can 0x0 be a valid virtual address in the address space
of an application ?
Yes.

If it is valid, then the location pointed by a NULL pointer
is also valid and application should not receive "SIGSEGV"
( i am talking of unix machine ) while trying to read that
location.

The declaration:

or
char *p = 0;

is not guaranteed to put the bit pattern 0xdeadbeef into p, even
on 32-bit machines, or the pattern 0xdeadbeef0xdeadbeef on 64-bit
machines. But it might.
Then how can i distinguish between a NULL pointer and an invalid
location ?

The code:
if (p == 0) { ... } /* integer constant zero */
or
if (p == NULL) { ... } /* integer constant zero */

might generate the assembly code:

cmpl r4,#0xdeadbeef (Compare p with the bit pattern deadbeef)
bne .L5
...
..L5:

While the code:

int i = 0;

if (p == i) { ... } /* i is *NOT* an integer constant zero */

might gnerate the assembly code:

cmpl r4, #0 (Compare p with the bit pattern 00000000 )
bne .L5
...
..L5:


Is this essential that NULL pointer should not point to any of
the location in the virtual address space ?

Lots of older implementations without virtual memory used a NULL
pointer bit pattern of all-bits-zero and address 0 was a valid
address in the virtual address space (e.g. you could read, and even
write, it without having anything nasty happen like SIGSEGV.)
However, the thing at address was NOT a valid C object. Sometimes
it was startup code. Sometimes it was a zero byte, so code like:
printf("%s", NULL);
wouldn't print garbage, and also to prevent address 0 from being
assigned as a valid C object. I prefer the implementation where
the above printf() produces a list of cusswords.
If NULL pointer should not essentially point to an invalid
location, then why we should always use NULL to be location 0x0,
can we use some other location as well ?

If you (a compiler writer) use a NULL pointer value of all-bits-zero,
you don't have to be so careful about translating "an integer
constant with value 0 in a pointer context" to a NULL pointer
representation with a different bit pattern. This takes care in
writing the compiler, it may make code slightly bigger and slower,
and it causes bogus bug reports from people trying to compile sloppy
code. And in assembly language, testing for zero is likely to be
faster. Probably most important, making the NULL pointer all-bits-zero
lets crap code (there's a LOT of it out there!) run and cuts down
on your tech support costs.
Is this necessary that whenever an application try to access
location pointed by NULL pointer, it should be aborted by kernel
by posting some signal ?

No. But it's a really, really good idea. So is deleting the
offending source code (all copies), but I haven't seen anyone do
that yet. And an application should be coded assuming that it
*MIGHT* be aborted if it does that.
Please i need your help, beacuse i am getting more confused
as i am reading more and more documents on NULL pointers.
thanx for any help in advance.....

Ignore the documents written by any US political party about
NULL pointers. They are just trying to drum up support to
tax them. And don't bid on any null pointers for sale on Ebay.

Gordon L. Burditt
 
M

Malcolm

Old Wolf said:
Chapter and verse? AFAIK there are several architectures where
zero is a valid location, and you can safely read and write from it.
This code is undefined

char *ptr = 0;

*ptr = 1;

it may segfault, or it may write the value 1 to location 0 in memory, or it
may cause little green eleves to appear on screen.

This code is OK

void foo(char *ptr)
{
assert(ptr != 0);
}

char ch;

foo(&ch);

as long as ch is a valid object, the address may never evaluate to 0 (NULL).

This code is implementation defined

int x = 0;
char *ptr = (char *) x;

*ptr = 1;

if your platform allows writes to a location represented by all bits zero,
then it is correct. However most platforms won't allow this.
 
J

Jack Klein

This code is undefined

char *ptr = 0;

*ptr = 1;

it may segfault, or it may write the value 1 to location 0 in memory, or it
may cause little green eleves to appear on screen.

This code is OK

void foo(char *ptr)
{
assert(ptr != 0);
}

char ch;

foo(&ch);

as long as ch is a valid object, the address may never evaluate to 0 (NULL).

This code is implementation defined

int x = 0;
char *ptr = (char *) x;

*ptr = 1;

if your platform allows writes to a location represented by all bits zero,
then it is correct. However most platforms won't allow this.

No, actually several common desk top operating systems that you happen
to be familiar with do not allow this. Unfortunately your desk top
chauvinism is totally incorrect as far as the vast majority of
platforms that run C is concerned.

On most processors, microcontrollers, and DSPs, that have C
implementations, which number orders of magnitude more than your desk
top platforms, you can access memory at address "all bits 0". Whether
there is any utility to doing so, and what might happen if you try to
write there, is another story. But a read access is totally benign,
the memory location exists, and the result is whatever it contains.
 
R

RCollins

Jack said:
No, actually several common desk top operating systems that you happen
to be familiar with do not allow this. Unfortunately your desk top
chauvinism is totally incorrect as far as the vast majority of
platforms that run C is concerned.

Er .. did't you just say the same thing Malcolm said? Or am I reading
you wrong?
On most processors, microcontrollers, and DSPs, that have C
implementations, which number orders of magnitude more than your desk
top platforms, you can access memory at address "all bits 0". Whether
there is any utility to doing so, and what might happen if you try to
write there, is another story. But a read access is totally benign,
the memory location exists, and the result is whatever it contains.

True; there are also machines where all-bits-0 is an invalid address,
and even machines (extinct, to my knowledge) where very low addresses
(including all-bits-0) represented actual register locations. However,
on all of these machines, it is _still_ up to the compiler to map a
constant 0 value to the NULL address (however it may be represented
internally).

Cheers,
Ron
 
M

Mabden

Old Wolf said:
"Mabden" <mabden@sbc_global.net> wrote in message

Chapter and verse? AFAIK there are several architectures where
zero is a valid location, and you can safely read and write from it.

K&R2 pg. 102 "C guarantees that zero is never a valid address for data..."
 
K

Keith Thompson

Mabden said:
K&R2 pg. 102 "C guarantees that zero is never a valid address for data..."

My copy of K&R2 isn't handy, but I presume "zero" refers to a null
pointer (which can be represented in source by a literal 0), not
necessarily to an all-bits-zero address.
 
J

junky_fellow

The declaration:

or
char *p = 0;

is not guaranteed to put the bit pattern 0xdeadbeef into p, even
on 32-bit machines, or the pattern 0xdeadbeef0xdeadbeef on 64-bit
machines. But it might.


The code:
if (p == 0) { ... } /* integer constant zero */
or
if (p == NULL) { ... } /* integer constant zero */

might generate the assembly code:

cmpl r4,#0xdeadbeef (Compare p with the bit pattern deadbeef)
bne .L5
...
.L5:

While the code:

int i = 0;

if (p == i) { ... } /* i is *NOT* an integer constant zero */

might gnerate the assembly code:

cmpl r4, #0 (Compare p with the bit pattern 00000000 )
bne .L5
...
.L5:




Lots of older implementations without virtual memory used a NULL
pointer bit pattern of all-bits-zero and address 0 was a valid
address in the virtual address space (e.g. you could read, and even
write, it without having anything nasty happen like SIGSEGV.)
However, the thing at address was NOT a valid C object. Sometimes
it was startup code. Sometimes it was a zero byte, so code like:
printf("%s", NULL);
wouldn't print garbage, and also to prevent address 0 from being
assigned as a valid C object. I prefer the implementation where
the above printf() produces a list of cusswords.


If you (a compiler writer) use a NULL pointer value of all-bits-zero,
you don't have to be so careful about translating "an integer
constant with value 0 in a pointer context" to a NULL pointer
representation with a different bit pattern. This takes care in
writing the compiler, it may make code slightly bigger and slower,
and it causes bogus bug reports from people trying to compile sloppy
code. And in assembly language, testing for zero is likely to be
faster. Probably most important, making the NULL pointer all-bits-zero
lets crap code (there's a LOT of it out there!) run and cuts down
on your tech support costs.


No. But it's a really, really good idea. So is deleting the
offending source code (all copies), but I haven't seen anyone do
that yet. And an application should be coded assuming that it
*MIGHT* be aborted if it does that.


Ignore the documents written by any US political party about
NULL pointers. They are just trying to drum up support to
tax them. And don't bid on any null pointers for sale on Ebay.

Gordon L. Burditt

thanx a lot to all of you for the valuable comments and help....
 
M

Mabden

Keith Thompson said:
data..."

My copy of K&R2 isn't handy, but I presume "zero" refers to a null
pointer (which can be represented in source by a literal 0), not
necessarily to an all-bits-zero address.

That would make a "pres" out of "u" and "me".
It refers to a location. There is no location zero in memory in C for data.

Where the hell is Dan Pop?!! Back me up, Dude.
 
K

Keith Thompson

Mabden said:
That would make a "pres" out of "u" and "me".
It refers to a location. There is no location zero in memory in C for data.

Where the hell is Dan Pop?!! Back me up, Dude.

You must be very brave to utter his name.
 
D

Default User

Keith said:
You must be very brave to utter his name.


I don't know why he keeps saying that. I explained all this to him once
on CLC++, but the message didn't get across.

He needs to engage his brain.




Brian Rodenborn
 
M

Michael Wojcik

K&R2 is not the standard. It does not specify the C language. It
describes it with considerable fidelity, but not perfectly; it
contains errors.[1]

It's not K&R's finest moment. Here's a bit more context:

If not, alloc must return some signal that no space is left. C
guarantees that zero is never a valid address for data, so a return
value of zero can be used to signal an abnormal event, in this case,
no space.

From the context it's clear that in this instance they're referring to
a pointer value - what's returned by their alloc() function. However,
the text fails to make clear that this does not apply to the actual
internal representation of an address. The use of "address" here is
infelicitous - it's either wrong or misleading. IMO this should be
added to the errata list.
That would make a "pres" out of "u" and "me".
It refers to a location. There is no location zero in memory in C for data.

Either the text is incorrect or you are misreading it. It's not
clear from the text itself which is the case. (If Dennis is reading
this thread, maybe he'll tell us what the intent of this sentence was.)

In C, *there is no relationship between a pointer value and the address
to which it refers*. In every C implementation, of course, there must
be some such relationship - but it certainly need not be as simple as
"pointer value is an address". There are extant conforming C implemen-
tations where that is not the case. And so while a pointer value of 0
must not refer to the location of any object in C, an object can exist
at address 0. A pointer to that object will not have value 0; that is
all.


1. http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html

--
Michael Wojcik (e-mail address removed)

Painful lark, labouring to rise!
The solemn mallet says:
In the grave's slot
he lies. We rot. -- Basil Bunting
 
O

Orhan Kavrakoglu

This code is undefined

char *ptr = 0;

*ptr = 1;
<snip>

This is only because 0 is converted to the internal value for
representing a NULL-pointer, isn't it?

Hmm let's see, how could we...

char *ptr = 0; /* ptr is a NULL pointer */
char **p = &ptr;

*p ^= *p; /* I am hoping to have cleared every bit of ptr */

If every bit of ptr is cleared and it has the value '0', it is no
longer necessarily a NULL pointer, is it?
 
M

Malcolm

RCollins said:
Er .. did't you just say the same thing Malcolm said? Or am I reading
you wrong?
I really don't understand the attitude. Of course what I meant was "the
platform that the OP is using probably won't allow this", but that sounds
rather patronising, as if people who don't write for PCs (which includes
myself) are in a superior category. There are of course lots of small
embedded systems out there, and it is probably technically correct to say
"more platforms" allow writes to memory location 0. However the accustion of
"desktop chauvanism" is ridiculous.
 

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,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top