faq why use p=NULL?

D

Default User

Rolf said:
Yes. Newsreaders usually offer functionality to cancel a posting as
well as supersede one. However, some
Most.

usenet servers don't seem to
handle it correctly,

Ignore cancel and supercede requests due to forging.
so your message might not be canceled completely.

It's best to assume that whatever you wrote is the way it is. If you
make a mistake, post a follow-up with the correction.



Brian
 
O

Old Wolf

Ian said:
Because you pass the pointer by value, so free() can't change the value
of the pointer.

Actually free() does change the value of the pointer. It's a bit of
an oddball function. (After the call, the pointer's value is
indeterminate; before the call, it wasn't).
 
I

Ian Collins

Old said:
Actually free() does change the value of the pointer. It's a bit of
an oddball function. (After the call, the pointer's value is
indeterminate; before the call, it wasn't).
I didn't know that, where is this behaviour documented?

The C standard make no mention of this.
 
P

Phlip

Ian said:
I didn't know that, where is this behaviour documented?

free() don't change no value of no stinkin' pointer.

Read the thread "Deleting and checking pointers" for a nauseatingly in-depth
analysis of 'delete'. In sumary:

- delete is not required to not change its pointer
- the bits of other pointers to the same memory shall not change

- reading any of those pointers - except thru their addresses
typecast to unsigned char * - is undefined behavior because
the pointer might live in a hardware register that no longer
contains the address of a valid memory location

If I have confused any parts of this list, blame that thread...
The C standard make no mention of this.

I expect the second two could apply...
 
R

Ron House

Rolf said:
Dervish wrote:


He votes for 0, because NULL is supposed to be only used in pointer context,
but still is an integer, which can sometimes lead to unexpected results.
When using 0 directly, the fact that it's an integer is not hidden.
Consider:

#include <iostream>

void f(int)
{
std::cout << "f(int) called\n";
}

void f(char*)
{
std::cout << "f(char*) called\n";
}

int main()
{
f(NULL); // oops, calls f(int)
}

You would have to cast NULL to char* to get the correct result, which is
less obvious than the fact that you need to cast literal 0.

Isn't the above argument the equivalent of saying that Stroustrup was
wrong to use 0 instead of (void*)0 ?
 
R

Rolf Magnus

Old said:
Actually free() does change the value of the pointer.

It doesn't. It even can't.
It's a bit of an oddball function. (After the call, the pointer's value is
indeterminate; before the call, it wasn't).

No. The pointer's value is exactly the same as before. However, the object
that it was pointing to is gone.
If you write a letter, and the house that it's supposed to go to is knocked
down, that won't magically change the address written on the letter.
However, it will be invalid, because there is no house at that address
anymore. It's just the same with a pointer to a destroyed object.
 
P

Phlip

No. The pointer's value is exactly the same as before.

Are you completely sure? What if the pointer lived in a register that
twitched, or something, when the memory it pointed to got changed?

(The example for free() was raised that a segment-offset system, with two
values for each pointer, could become invalid when the OS releases the
segment. Not the same as changing the pointer value, but pretty danged
close.)
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Phlip said:
Are you completely sure? What if the pointer lived in a register that
twitched, or something, when the memory it pointed to got changed?

In this case the hardware is modifying the pointer, not free. You can also
have an int variable that lives in a memory address that is incremented
when is read. If your c++ compiler creates that type of things without some
special way to ask for it, is not a standard conforming compiler.
(The example for free() was raised that a segment-offset system, with two
values for each pointer, could become invalid when the OS releases the
segment. Not the same as changing the pointer value, but pretty danged
close.)

Reasoning that way, if you have an i integer variable used as index in a
string, if you erase the content of the string you are pretty close to
change the value of i. Can be seen that way, but it is confusing, the value
of i has no changed at all. You can explain that situation by saying that
the index has been invalidated, and nobody will be confused.
 
P

Phlip

Julián Albo said:
Reasoning that way, if you have an i integer variable used as index in a
string, if you erase the content of the string you are pretty close to
change the value of i. Can be seen that way, but it is confusing, the
value of i has no changed at all. You can explain that situation by saying
that the index has been invalidated, and nobody will be confused.

In the segment-offset situation, when the pointer is read as an rvalue,
hardware might assemble the segment and offset into a composite thing. This
is a common form of virtual memory. So an invalid segment or offset might
cause a memory exception.

(Of course these issues are leaving us MS Windows developers salivating for
a C++ implementation that actually occassionally returns memory to the OS
at 'delete' time. Many implementations just grow and grow forever!)
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Phlip said:
In the segment-offset situation, when the pointer is read as an rvalue,
hardware might assemble the segment and offset into a composite thing.
This is a common form of virtual memory. So an invalid segment or offset
might cause a memory exception.

I don't see why the compiler needs to do that if you are only doing
something with the value of the pointer but not dereferecing it. It is
always possible, and probably more efficient, to work with the composite
without using segment registers. I don't think any compiler writer will
violate standards and programmers expectations for no benefit.
 
P

Phlip

Julián Albo said:
I don't see why the compiler needs to do that if you are only doing
something with the value of the pointer but not dereferecing it.

In C++, you don't pay for what you don't use. Generally.

Consider a slow opcode FOO that carefully copied out the segment and offset
from such a hypothetical pointer. Suppose this CPU also had a fast opcode
BAR that exploited the CPU's microcode to copy out the pointer's value, but
this BAR threw an automatic hardware exception if the segment and offset
are not valid.

(Such hardware exceptions are often how overcommitted virtual memory works.)

A C++ compiler cannot guess which pointers are valid and which should not be
used as rvalues. This code causes undefined behavior:

int * p = new int;
delete p;
assert(NULL != p); // <-- undefined behavior

Our hypothetical compiler must use the BAR opcode in that assertion, because
all the times we use pointers for defined behavior must be fast.

(BTW the assertion itself is well-formed, and won't cause the first
undefined behavior.)
 
D

dan2online

Rolf said:
If a function like

void f(const char* p, ...);

expects pointers to char until there is a null pointer, you would have to
write:

f("hello", "world", "this", "is", "a", "test", (char*)NULL);

If you use NULL without the cast, the behavior is undefined because you pass
the wrong type.

NULL can be considered as one kind of MARK, so the programmer will
decide what action to do, I think.
 
P

Phlip

dan2online said:
NULL can be considered as one kind of MARK, so the programmer will
decide what action to do, I think.

The ellipses operator ... is type-hostile. A NULL might go in as an int, not
a pointer, and might be the wrong size. A programmer cannot control this
situation, though I suspect it will appear to work correctly (and vaguely
lie within the realm of defined behavior) on platforms where ints and
pointers are the same size.

Whoever suggested ... is advised to simply provide default arguments for as
many strings as they need:

void f (
char const * p1,
char const * p2 = NULL,
char const * p3 = NULL,
char const * p4 = NULL,
char const * p5 = NULL,
char const * p6 = NULL,
char const * p7 = NULL,
char const * p8 = NULL,
char const * p9 = NULL
);
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Phlip said:
Consider a slow opcode FOO that carefully copied out the segment and
offset from such a hypothetical pointer. Suppose this CPU also had a fast
opcode BAR that exploited the CPU's microcode to copy out the pointer's
value, but this BAR threw an automatic hardware exception if the segment
and offset are not valid.

Too much suppositions for a reasonable discussion. I'm sure you can imagine
an architecture where your idea makes sense, but I don't think real code
for existent machines must be invalidated for the convenience of imaginary
ones.
 
K

Kai-Uwe Bux

Phlip said:
Are you completely sure? What if the pointer lived in a register that
twitched, or something, when the memory it pointed to got changed?

This must have been said elsewhere before: free() receives the pointer by
value. Thus, we have two pointer objects and the one that free() could
change easily is its local copy. Whether it does that appears to be an
implementation detail not observable from the outside.

On the other hand, if p is a pointer variable the call free(p) will release
the memory and invalidate the pointer. After that, any lvalue-rvalue
conversion on p is undefined behavior. In other words, even if free() would
somewhat magically alter the content of the object p (by guessing its
address or tracing all pointer objects that point to the released region),
you would have no means of finding out. Any attempt will result in
undefined behavior as reading out the content of p is an unholy act.


Best

Kai-Uwe Bux
 

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,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top