By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,963 Members | 2,122 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,963 IT Pros & Developers. It's quick & easy.

faq why use p=NULL?

P: n/a
Hi,
This is c code , but the question is same to c++ £®new/delete£©.

char* p = malloc(10);
strcpy(p, "hello");
printf("%s\n", p);
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?
p = NULL; // If we do not use p after call free , we can delete this line
..

And someone write p = NULL is not a good idea for Unix.

Thanks.
Apr 18 '06 #1
Share this Question
Share on Google+
35 Replies


P: n/a

"fcvcnet" <fc*****@163.com> skrev i meddelandet
news:e2**********@news.cn99.com...
Hi,
This is c code , but the question is same to c++ £®new/delete£©.

char* p = malloc(10);
strcpy(p, "hello");
printf("%s\n", p);
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?
p = NULL; // If we do not use p after call free , we can delete this line .

And someone write p = NULL is not a good idea for Unix.

Thanks.


Hello,

This does not answer your question byt why replace the code with the
following?
printf("%s\n","hello");

Regards,
Peter Jansson
http://www.jansson.net/
Apr 18 '06 #2

P: n/a
Hi,
Do you mean "byt why not replace the code with the following?" ?
If it is , I think use "p" instead of "hello" is simple.
And I think if use "hello" , the compiler will allocate a chunck of memory
to hold "hello".
Apr 18 '06 #3

P: n/a
Hi,
Can somebody introduce any book about c++ with memory, I have so many
question about this part.
Thank you very much.
Apr 18 '06 #4

P: n/a
fcvcnet wrote:
Hi,
This is c code , but the question is same to c++ £®new/delete£©.

char* p = malloc(10);
malloc returns void * pointer, so the statement is changed into:
char *p = (char *)malloc(10);
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?
p = NULL; // If we do not use p after call free , we can delete thisline
. you can wrap the free function that has this ability, but the argument
is the reference to the pointer.

void free_wrapper (void **pp)
{
free ( *pp );
*pp = NULL;
}
And someone write p = NULL is not a good idea for Unix.


Why? I think NULL is a cleaner way to stand for Null pointer than 0 or
(void *)0 at least.
But for C++, it is a good point to introduce null object design
pattern instead of NULL.

Apr 18 '06 #5

P: n/a
fcvcnet wrote:
Hi,
This is c code , but the question is same to c++ £®new/delete£©.

char* p = malloc(10); Don't use malloc, use new.
strcpy(p, "hello");
printf("%s\n", p); Why not printf("hello\n"); ?
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()? Because you pass the pointer by value, so free() can't change the value
of the pointer.
p = NULL; // If we do not use p after call free , we can delete this line
..

And someone write p = NULL is not a good idea for Unix.

Who and where?

--
Ian Collins.
Apr 18 '06 #6

P: n/a
yes, I reference from
http://users.actcom.co.il/~choo/lupg...x-memory.html#
c_alloc
char* p = malloc(10);
And someone write p = NULL is not a good idea for Unix.
Why? I think NULL is a cleaner way to stand for Null pointer than 0 or
(void *)0 at least.
But for C++, it is a good point to introduce null object design
pattern instead of NULL.
sorry , I am wrong , I made a mistake of this.

Apr 18 '06 #7

P: n/a

"fcvcnet" <fc*****@163.com> skrev i meddelandet
news:e2**********@news.cn99.com...
Hi,
Do you mean "byt why not replace the code with the following?" ?
If it is , I think use "p" instead of "hello" is simple.
And I think if use "hello" , the compiler will allocate a chunck of memory
to hold "hello".


Hi,

Yes, I did mean "...but why not replace..."

The compiler will also allocate a chunck of memory to hold "hello" for the
following part of your code:
strcpy(p, "hello");

Regards,
Peter Jansson
http://www.jansson.net/
Apr 18 '06 #8

P: n/a
Thanks.
Because you pass the pointer by value, so free() can't change the value
of the pointer.

now I know.
And someone write p = NULL is not a good idea for Unix.

Who and where?

sorry for that I made a mistake.

BTW, Can I edit/delete the news I have had posted for there is a mistake I
made and that bring much more misunderstand?
Apr 18 '06 #9

P: n/a
>BTW, Can I edit/delete the news I have had posted for there is a mistake I
made and that bring much more misunderstand?


No.

Regarding the p=NULL issue, if the pointer object goes out of scope it
indeed is redundant. The language doesn't guard against this kind of
stuff: you have to keep track manually what is freed and what isn't
(likewise, what is allocated and what isn't). This is why it's a good
idea generally to zero pointers to memory that is already freed (to
avoid freeing the same memory twice or more).

But, if the pointer goes out of scope, knock yourself out and not zero
it.

Apr 18 '06 #10

P: n/a
One more thing, goes without saying but saying it anyway. If you zero
pointer to memory that is freed, you easily propagate the information
to other parts of your program that the pointer doesn't point to valid
memory. (there must be someway to do this, and zeroing the pointer is
the obvious way).

Apr 18 '06 #11

P: n/a
fcvcnet wrote:
Hi,
Do you mean "byt why not replace the code with the following?" ?
If it is , I think use "p" instead of "hello" is simple.
The write:

char* p = "hello";
And I think if use "hello" , the compiler will allocate a chunck of memory
to hold "hello".


Yes, but it will do that either way. Somewhere in memory, there has to be
the "hello". Your version just dynamically allocates a second chunk of
memory and then copies the "hello" over to that. Later, it deallcates the
memory again. So you do much more work than needed.

Apr 18 '06 #12

P: n/a
dan2online wrote:
And someone write p = NULL is not a good idea for Unix.
Why? I think NULL is a cleaner way to stand for Null pointer than 0 or
(void *)0 at least.


Maybe it would. However, NULL is not a null pointer. It's an integer
constant (actually a macro that is replaced by one).
But for C++, it is a good point to introduce null object design
pattern instead of NULL.


AFAIK, the next version of the C++ standard will address this issue.

Apr 18 '06 #13

P: n/a
fcvcnet wrote:
Thanks.
Because you pass the pointer by value, so free() can't change the value
of the pointer.

now I know.
> And someone write p = NULL is not a good idea for Unix.
>

Who and where?

sorry for that I made a mistake.

BTW, Can I edit/delete the news I have had posted for there is a mistake
I made and that bring much more misunderstand?


Yes. Newsreaders usually offer functionality to cancel a posting as well as
supersede one. However, some usenet servers don't seem to handle it
correctly, so your message might not be canceled completely.

Apr 18 '06 #14

P: n/a

Rolf Magnus wrote:
fcvcnet wrote:
Hi,
Do you mean "byt why not replace the code with the following?" ?
If it is , I think use "p" instead of "hello" is simple.


The write:

char* p = "hello";
And I think if use "hello" , the compiler will allocate a chunck of memory
to hold "hello".


Yes, but it will do that either way. Somewhere in memory, there has to be
the "hello". Your version just dynamically allocates a second chunk of
memory and then copies the "hello" over to that. Later, it deallcates the
memory again. So you do much more work than needed.


My understanding of the OP's question was why you after delete p should
set p to 0. The silly code between new and delete (well - malloc and
free, but the op explains the problem is the same in both cases) was
just more or less random bits of code.

/Peter

Apr 18 '06 #15

P: n/a
With C++ it's simple. If You delete 0 then delete does nothing.

BTW.
delete p;
p = 0; // or NULL
Can be changed to:
delete p, 0;


Apr 18 '06 #16

P: n/a
>Maybe it would. However, NULL is not a null pointer. It's an integer
constant (actually a macro that is replaced by one).

Better to say that in C it can be macro. In C++ it should be #defined
as just 0. With no type. AFAIK Stroustrup votes for 0 and not NULL
since once can accidentally include file with invalid or old style NULL
definition.

Apr 18 '06 #17

P: n/a
Dervish <DA*******@yandex.ru> wrote:
Maybe it would. However, NULL is not a null pointer. It's an integer
constant (actually a macro that is replaced by one).


Better to say that in C it can be macro. In C++ it should be #defined
as just 0.


....which is a macro.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Apr 18 '06 #18

P: n/a
Dervish wrote:
Maybe it would. However, NULL is not a null pointer. It's an integer
constant (actually a macro that is replaced by one).
Better to say that in C it can be macro.


I didn't talk about C, since we're in a C++ newsgroup.
In C++ it should be #defined as just 0. With no type.
First of all, 0 does have a type. Any expression has a type. The type of
literal 0 is int. Second, NULL can be defined as anything that resolves to
a constant integral expression with the value 0, so

#define NULL (4 + 3 - 7)

would also be ok.
AFAIK Stroustrup votes for 0 and not NULL since once can accidentally
include file with invalid or old style NULL definition.


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.

Another problem (though more relevant to C than C++) is that you have to be
careful with functions with variable argument lists, because you have to
cast NULL to a pointer here too if you actually want to pass a pointer.

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.

Apr 18 '06 #19

P: n/a

"fcvcnet" <fc*****@163.com> wrote in message
news:e2**********@news.cn99.com...
Hi,
This is c code , but the question is same to c++ £®new/delete£©.

char* p = malloc(10);
strcpy(p, "hello");
printf("%s\n", p);
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?
p = NULL; // If we do not use p after call free , we can delete this
line
.

And someone write p = NULL is not a good idea for Unix.

Thanks.


Here is the answer from the perspective of the C++ delete operator:

http://public.research.att.com/~bs/b...ml#delete-zero

I would say the same considerations apply to malloc.

Cy
Apr 18 '06 #20

P: n/a
Rolf Magnus wrote:
fcvcnet wrote:
Thanks.
Because you pass the pointer by value, so free() can't change the
value >> of the pointer.
now I know.
> And someone write p = NULL is not a good idea for Unix.
>
Who and where?

sorry for that I made a mistake.

BTW, Can I edit/delete the news I have had posted for there is a
mistake I made and that bring much more misunderstand?


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

Apr 18 '06 #21

P: n/a
Ian Collins wrote:
fcvcnet wrote:
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?


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).

Apr 18 '06 #22

P: n/a
Old Wolf wrote:
Ian Collins wrote:
fcvcnet wrote:
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?


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 didn't know that, where is this behaviour documented?

The C standard make no mention of this.

--
Ian Collins.
Apr 18 '06 #23

P: n/a
Ian Collins wrote:
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?


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...

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 18 '06 #24

P: n/a
Phlip wrote:
Read the thread "Deleting and checking pointers"


On the moderated newsgroup!!

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 18 '06 #25

P: n/a
Rolf Magnus wrote:
Dervish wrote:

AFAIK Stroustrup votes for 0 and not NULL since once can accidentally
include file with invalid or old style NULL definition.

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 ?

--
Ron House ho***@usq.edu.au
http://www.sci.usq.edu.au/staff/house
Apr 19 '06 #26

P: n/a
Old Wolf wrote:
Ian Collins wrote:
fcvcnet wrote:
free(p);
// free just add p to the free list of memory, and do nothing else.
// Is there any use of p? If we never use p why not just nullify p in
free()?
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 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.

Apr 20 '06 #27

P: n/a
Rolf Magnus wrote:
Actually free() does change the value of the pointer.
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.)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 20 '06 #28

P: n/a
Phlip wrote:
Actually free() does change the value of the pointer. 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?


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.

--
Salu2

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
Apr 20 '06 #29

P: n/a
Juli√°n Albo wrote:
(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.


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!)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 20 '06 #30

P: n/a
Phlip wrote:
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.

--
Salu2

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
Apr 20 '06 #31

P: n/a
Juli√°n Albo wrote:
Phlip wrote:
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.


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.)

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 20 '06 #32

P: n/a

Rolf Magnus wrote:
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.

Apr 20 '06 #33

P: n/a
dan2online wrote:
Rolf Magnus wrote:
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.


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
);

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 20 '06 #34

P: n/a
Phlip wrote:
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.

--
Salu2

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
Apr 20 '06 #35

P: n/a
Phlip wrote:
Rolf Magnus wrote:
Actually free() does change the value of the pointer.

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?


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

Apr 20 '06 #36

This discussion thread is closed

Replies have been disabled for this discussion.