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

C free

P: n/a
Hello,

Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char));
p=p+50;
free(p);

Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?

How are these malloc and free linked internelly?

Thanks,
Reddy

Jun 25 '06 #1
Share this Question
Share on Google+
33 Replies


P: n/a

Reddy wrote:
Hello,

Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char));
p=p+50;
free(p);

Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?
Neither ; it evokes undefined behaviour. You can only call free()
with either the NULL pointer or with a pointer which has a
value which was previously returned by malloc or similar functions.
How are these malloc and free linked internelly?


I'm not sure what you're asking here but I suspect it's up to
implementation.

Spiros Bousbouras

Jun 25 '06 #2

P: n/a
sp****@gmail.com wrote:
Reddy wrote:
Hello,

Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char));
p=p+50;
free(p);

Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?


Neither ; it evokes undefined behaviour. You can only call free()
with either the NULL pointer or with a pointer which has a
value which was previously returned by malloc or similar functions.


In addition there are potential problems with the use of malloc. You
don't need to cast the return value of malloc (if the compiler complains
you have something else wrong) and sizeof(char) is 1 by definition so
its use is pointless. So the malloc call should be either

char *p = malloc(100 * sizeof *p);

or

char *p = malloc(100);

Search the group for lots of discussion on this point.
How are these malloc and free linked internelly?


I'm not sure what you're asking here but I suspect it's up to
implementation.


I also suspect it is irrelevant to any properly written C program.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jun 25 '06 #3

P: n/a

"Reddy" <he***************@gmail.com> wrote in
Hello,

Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char));
p=p+50;
free(p);

Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?

How are these malloc and free linked internelly?

The way malloc() works, on a simple system at least, is that there is a big
pool of memory.
Then we have a structure something like this

struct blockcontrol
{
blockcontrol *prev;
blockcontrol *next;
size_t length;
};

When you call malloc(), it finds a block of contiguous memory that is large
enough, and then it fills in the blockcontrol structure, so it knows how big
the allocated block is, and where the adjacent allocated free or allocated
blocks are. The precise details vary and we won't worry about them here.

Now comes the clever part. It returns a pointer to the memory immediately
after the block control structure it has filled out. The caller can then use
that memory as he likes.
When the caller calls free, the free function subtracts the size of a
blockcontrol structure from the pointer, and then it has access to all the
data. It can return the memory to the pool, merge consecutive free blocks,
and so on.

You will see that trying to free half the memory allocated, by passing a
pointer in the middle of the block allocated, will destroy this scheme.
free() won't be able to find the blockcontrol structure
Jun 25 '06 #4

P: n/a
>Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char)); ^^^^^^^^ this cast is useless.p=p+50;
free(p);

Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?
free() is *NEVER* guaranteed to *CLEAR* memory. If you want
that, try memset().

If you pass a pointer to free() which you did not get from malloc()
or realloc(), you invoke the wrath of undefined behavior, which is
exactly what the above does. You might get a smegmentaion fault,
or it might spend all the money in your pocket.
How are these malloc and free linked internelly?


With chain-link fence?

Gordon L. Burditt
Jun 25 '06 #5

P: n/a
"Reddy" <he***************@gmail.com> writes:
Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char));
Never cast the result of malloc(). It can mask certain errors, such
as failing to #include <stdlib.h>. Preferred:

char *p = malloc(100 * sizeof *p);

or, since sizeof(char) is 1 by definition:

char *p = malloc(100);

Always check whether malloc succeeded. (It returns NULL if it fails.)
p=p+50;
Undefined behavior of malloc() failed.
free(p);
Kaboom!

free() may only be called with the result of a previous malloc() (or
calloc() or realloc()) or with a null pointer. Anything else causes
undefined behavior, and is very likely to mess things up quite
thoroughly.
Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.
How are these malloc and free linked internelly?


As if by magic. The runtime system maintains internal information to
enable it to allocate and deallocate memory. How it does this is
entirely up to the implementation, and varies from one system to
another. The functions work as described in the standard; that's all
you know, and if you happen to know the internal details, you
shouldn't depend on them.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 25 '06 #6

P: n/a
Keith Thompson wrote:
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.


The freed pointer value itself is indeterminate.
The memory in question, is no longer an object.

--
pete
Jun 25 '06 #7

P: n/a
In article <44***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:
Keith Thompson wrote:
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.


The freed pointer value itself is indeterminate.
The memory in question, is no longer an object.


Which is probably a good thing. It was getting tired of being treated
like an object.

Jun 25 '06 #8

P: n/a
In article <CM********************@bt.com>,
Malcolm <re*******@btinternet.com> wrote:
When you call malloc(), it finds a block of contiguous memory that is large
enough, and then it fills in the blockcontrol structure, so it knows how big
the allocated block is, and where the adjacent allocated free or allocated
blocks are. The precise details vary and we won't worry about them here. Now comes the clever part. It returns a pointer to the memory immediately
after the block control structure it has filled out. The caller can then use
that memory as he likes.
When the caller calls free, the free function subtracts the size of a
blockcontrol structure from the pointer, and then it has access to all the
data. It can return the memory to the pool, merge consecutive free blocks,
and so on.


Implementation details that are not true in all systems.
--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
Jun 26 '06 #9

P: n/a
Reddy wrote:

Hello,

Can someone clarify this?

char *p = (char *) malloc (100*sizeof(char));
p=p+50;
free(p);

Does free clear all the 100 bytes of memory or only 50 as it is
pointing to 51st byte of memory now?
By freeing a pointer that was *not* returned by "malloc()", you
have evoked undefined behavior.

The C standard *not* withstanding, I can pretty much guarantee you
that by freeing "p=p+50", you have royally trashed out the workings
used by "malloc()".
How are these malloc and free linked internelly?

How "malloc()" and "free()" work internally is implementation
dependent. Different implementations are free to do it in
different ways and still be compliant with the standard.

--
+----------------------------------------------------------------+
| Charles and Francis Richmond richmond at plano dot net |
+----------------------------------------------------------------+
Jun 26 '06 #10

P: n/a
pete wrote:
Keith Thompson wrote:
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.


The freed pointer value itself is indeterminate.


I expect it to be the same value that it was last assigned. Why do you
think it is indeterminate?

--
Thad
Jun 27 '06 #11

P: n/a
Thad Smith <Th*******@acm.org> writes:
pete wrote:
Keith Thompson wrote:
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.

The freed pointer value itself is indeterminate.


I expect it to be the same value that it was last assigned. Why do
you think it is indeterminate?


Because the standard says so.

C99 6.2.4p2:

The value of a pointer becomes indeterminate when the object it
points to reaches the end of its lifetime.

I would expect, in most implementations, that the pointer passed to
free() will retain its previous representation (it's been argued that
this is required), and that it will compare equal to a saved copy of
its value from before the call to free(). More concretely:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int *ptr = malloc(sizeof *ptr);
int *saved_ptr = ptr;
if (ptr == NULL) {
printf("malloc failed\n");
}
else {
free(ptr);
if (ptr == saved_ptr) {
printf("equal\n");
}
else {
printf("not equal\n");
}
}
return 0;
}

I would be surprised if this program printed "not equal" in any
implementation, but the standard permits it to do so -- or to print
"fnord", for that matter.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 27 '06 #12

P: n/a
Thad Smith wrote:
pete wrote:
Keith Thompson wrote:
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.

The freed pointer value itself is indeterminate.

I expect it to be the same value that it was last assigned. Why do you
think it is indeterminate?


Perhaps because he has read the Standard. Specifically,
section 6.2.4 paragraph 2:

[...] The value of a pointer becomes indeterminate
when the object it points to reaches the end of
its lifetime.

Already I hear your plaintive cry: "Well, so, but why?"

On many machines, the value of a pointer is an address
and the value has meaning whether or not the memory at that
address is "occupied" by any of the program's objects. But
at a little more abstract level, the value of a pointer is
a reference to an object -- and if there is no object, there
can be no reference to it. A pointer that once pointed to an
object thus loses its value when the object ceases to exist.

Here is a pointer: "The last paragraph on the seventeenth
page of the fourth book on the fifth shelf in the second room
on the right as you come through the main entrance of the City
Library." It's a pointer because it's a reference, and using
the reference you can look up what it refers to.

Alas! The City is Alexandria and the Library was burned
multiple times by multiple conquerors many centuries ago. The
above is no longer a reference, but just a string of useless
words -- in fact, "valueless" words.

"514 Elm Street" looks like it might be an address, and
you might write it on an envelope. But if the space between
512 and 516 is a vacant lot, will the Post Office deliver
that letter? No: They will return it to you as undeliverable,
and might even mark it "No such address."

C's model of storage allows for addresses that carry more
"structure" than simple numbers. Most machines today do not
take advantage of this freedom, but who knows what will come
tomorrow? If tomorrow brings structured addresses, C will be
ready for them.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jun 27 '06 #13

P: n/a
Thank you all for your responses...

Regards,
Reddy
Eric Sosman wrote:
Thad Smith wrote:
pete wrote:
Keith Thompson wrote:

free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.
The freed pointer value itself is indeterminate.

I expect it to be the same value that it was last assigned. Why do you
think it is indeterminate?


Perhaps because he has read the Standard. Specifically,
section 6.2.4 paragraph 2:

[...] The value of a pointer becomes indeterminate
when the object it points to reaches the end of
its lifetime.

Already I hear your plaintive cry: "Well, so, but why?"

On many machines, the value of a pointer is an address
and the value has meaning whether or not the memory at that
address is "occupied" by any of the program's objects. But
at a little more abstract level, the value of a pointer is
a reference to an object -- and if there is no object, there
can be no reference to it. A pointer that once pointed to an
object thus loses its value when the object ceases to exist.

Here is a pointer: "The last paragraph on the seventeenth
page of the fourth book on the fifth shelf in the second room
on the right as you come through the main entrance of the City
Library." It's a pointer because it's a reference, and using
the reference you can look up what it refers to.

Alas! The City is Alexandria and the Library was burned
multiple times by multiple conquerors many centuries ago. The
above is no longer a reference, but just a string of useless
words -- in fact, "valueless" words.

"514 Elm Street" looks like it might be an address, and
you might write it on an envelope. But if the space between
512 and 516 is a vacant lot, will the Post Office deliver
that letter? No: They will return it to you as undeliverable,
and might even mark it "No such address."

C's model of storage allows for addresses that carry more
"structure" than simple numbers. Most machines today do not
take advantage of this freedom, but who knows what will come
tomorrow? If tomorrow brings structured addresses, C will be
ready for them.

--
Eric Sosman
es*****@acm-dot-org.invalid


Jun 27 '06 #14

P: n/a
Keith Thompson wrote:
I would expect, in most implementations, that the pointer passed to
free() will retain its previous representation (it's been argued that
this is required),


The standard explicitly allows representations to change during writes,
but not explicitly during reads, and since every object can be accessed
as an array of unsigned char, where each element is itself an object
which must "[retain] its last-stored value throughout its lifetime", I
would've thought this is required.

However, according to
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_260.htm
it is not. I'm not sure what to say about it, though, other than that
another part of the response already directly contradicts the standard:

"If two objects have identical bit-pattern representations and their
types are the same they may still compare as unequal [...]"

6.2.6.1#4: "Two values (other than NaNs) with the same object
representation compare equal,"

"[...] (for example if one object has an indeterminate value) and if
one is an indeterminate value attempting to read such an object invokes
undefined behavior."

If either is an indeterminate value, the behaviour is undefined before
any comparison is made. This means indeterminate values are not an
example of the above.

Jun 27 '06 #15

P: n/a

Eric Sosman wrote:
Thad Smith wrote:
pete wrote:
Keith Thompson wrote:

free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.
The freed pointer value itself is indeterminate.

I expect it to be the same value that it was last assigned. Why do you
think it is indeterminate?


Perhaps because he has read the Standard. Specifically,
section 6.2.4 paragraph 2:

[...] The value of a pointer becomes indeterminate
when the object it points to reaches the end of
its lifetime.

Already I hear your plaintive cry: "Well, so, but why?"

On many machines, the value of a pointer is an address
and the value has meaning whether or not the memory at that
address is "occupied" by any of the program's objects. But
at a little more abstract level, the value of a pointer is
a reference to an object -- and if there is no object, there
can be no reference to it. A pointer that once pointed to an
object thus loses its value when the object ceases to exist.

Here is a pointer: "The last paragraph on the seventeenth
page of the fourth book on the fifth shelf in the second room
on the right as you come through the main entrance of the City
Library." It's a pointer because it's a reference, and using
the reference you can look up what it refers to.

Alas! The City is Alexandria and the Library was burned
multiple times by multiple conquerors many centuries ago. The
above is no longer a reference, but just a string of useless
words -- in fact, "valueless" words.

"514 Elm Street" looks like it might be an address, and
you might write it on an envelope. But if the space between
512 and 516 is a vacant lot, will the Post Office deliver
that letter? No: They will return it to you as undeliverable,
and might even mark it "No such address."


Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?

Spiros Bousbouras

Jun 27 '06 #16

P: n/a

sp****@gmail.com wrote:

Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?


Probably, as "%p" requires `void *`. ;-)

If you fix that (by casting to `void *`), I don't think it is.
Trying to print `*p` would be though (with "%d", obviously).

It's the dereferencing the dud pointer that causes UB, not accessing
it's value.

Jun 27 '06 #17

P: n/a
"Vladimir Oka" <no****@btopenworld.com> writes:
sp****@gmail.com wrote:
Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?


Probably, as "%p" requires `void *`. ;-)

If you fix that (by casting to `void *`), I don't think it is.
Trying to print `*p` would be though (with "%d", obviously).

It's the dereferencing the dud pointer that causes UB, not accessing
it's value.


Yes, it's undefined behavior. As I mentioned elsethread, C99 6.2.4p2
says:

The value of a pointer becomes indeterminate when the object it
points to reaches the end of its lifetime.

You're very likely to get away with this, but any attempt to even look
at the value of an indeterminate pointer invokes undefined behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 27 '06 #18

P: n/a

Keith Thompson wrote:
"Vladimir Oka" <no****@btopenworld.com> writes:
sp****@gmail.com wrote:
Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?


Probably, as "%p" requires `void *`. ;-)

If you fix that (by casting to `void *`), I don't think it is.
Trying to print `*p` would be though (with "%d", obviously).

It's the dereferencing the dud pointer that causes UB, not accessing
it's value.


Yes, it's undefined behavior. As I mentioned elsethread, C99 6.2.4p2
says:

The value of a pointer becomes indeterminate when the object it
points to reaches the end of its lifetime.

You're very likely to get away with this, but any attempt to even look
at the value of an indeterminate pointer invokes undefined behavior.


Hmm. The Standard obviously makes a difference between UB and
`indeterminate` value, as the sentence just before the one you quote
explicitely says that trying to refer to an object after its lifetime
ends invokes UB (to losely paraphrase). The whole paragraph is:

The lifetime of an object is the portion of program execution during
which
storage is guaranteed to be reserved for it. An object exists, has a
constant
address, and retains its last-stored value throughout its lifetime.
If an object
is referred to outside of its lifetime, the behavior is undefined.
The value of a
pointer becomes indeterminate when the object it points to reaches
the end
of its lifetime.

I'm inclined to interpret "indeterminate" more as "you may get
unexpected values on inspection" than "even looking invokes UB".
Probably something along the lines of Schroedinger's cat (apologies for
likely misspelling of the great man's name).

Jun 27 '06 #19

P: n/a
Vladimir Oka wrote:
sp****@gmail.com wrote:
Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?


Probably, as "%p" requires `void *`. ;-)

If you fix that (by casting to `void *`), I don't think it is.
Trying to print `*p` would be though (with "%d", obviously).

It's the dereferencing the dud pointer that causes UB, not accessing
it's value.


No, even accessing it can cause UB. Section 6.2.4 para 2 of N1124 says:

| The lifetime of an object is the portion of program execution during
| which storage is guaranteed to be reserved for it. An object exists,
| has a constant address,25) and retains its last-stored value
| throughout its lifetime.26) If an object is referred to outside of its
| lifetime, the behavior is undefined. The value of a pointer becomes
| indeterminate when the object it points to reaches the end of its
| lifetime.

So the pointer becomes indeterminate. An indeterminate value is either
an unspecified value or a trap representation, and if it is a trap
reading it is UB.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jun 27 '06 #20

P: n/a
Thad Smith wrote:

pete wrote:
Keith Thompson wrote:
free() doesn't clear memory; it deallocated it (i.e., makes it
available for later allocation). The contents of the memory are
indeterminate.


The freed pointer value itself is indeterminate.


I expect it to be the same value that it was last assigned.
Why do you think it is indeterminate?


Like Eric Sosman said, because that's what the standard says.

The only possibilties for a pointer value are:
1 null pointer
2 pointer to object
3 pointer to one past object
4 indeterminate

A freed pointer isn't any of the first three.

--
pete
Jun 27 '06 #21

P: n/a

Flash Gordon wrote:
Vladimir Oka wrote:
sp****@gmail.com wrote:
Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?


Probably, as "%p" requires `void *`. ;-)

If you fix that (by casting to `void *`), I don't think it is.
Trying to print `*p` would be though (with "%d", obviously).

It's the dereferencing the dud pointer that causes UB, not accessing
it's value.


No, even accessing it can cause UB. Section 6.2.4 para 2 of N1124 says:

| The lifetime of an object is the portion of program execution during
| which storage is guaranteed to be reserved for it. An object exists,
| has a constant address,25) and retains its last-stored value
| throughout its lifetime.26) If an object is referred to outside of its
| lifetime, the behavior is undefined. The value of a pointer becomes
| indeterminate when the object it points to reaches the end of its
| lifetime.

So the pointer becomes indeterminate. An indeterminate value is either
an unspecified value or a trap representation, and if it is a trap
reading it is UB.


Ah, OK. Didn't occur to me that it may happent to be a trap. Thanks for
clarifying that.

Jun 27 '06 #22

P: n/a
Vladimir Oka wrote:
Hmm. The Standard obviously makes a difference between UB and
`indeterminate` value,
Using one causes the other.
I'm inclined to interpret "indeterminate" more as "you may get
unexpected values on inspection" than "even looking invokes UB".


But you're misinterpreting UB.

N869
3. Terms and definitions
3.18
[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements

--
pete
Jun 27 '06 #23

P: n/a
pete wrote:
Thad Smith wrote:

pete wrote:
Keith Thompson wrote:

>free() doesn't clear memory; it deallocated it (i.e., makes it
>available for later allocation). The contents of the memory are
>indeterminate.

The freed pointer value itself is indeterminate.


I expect it to be the same value that it was last assigned.
Why do you think it is indeterminate?


Like Eric Sosman said, because that's what the standard says.

The only possibilties for a pointer value are:
1 null pointer
2 pointer to object
3 pointer to one past object
4 indeterminate

A freed pointer isn't any of the first three.


4 should be "trap representation". An indeterminate pointer value can
turn out to be a valid pointer value, even though you cannot rely on
this.

Jun 27 '06 #24

P: n/a
pete wrote:
Vladimir Oka wrote:
Hmm. The Standard obviously makes a difference between UB and
`indeterminate` value,


Using one causes the other.
I'm inclined to interpret "indeterminate" more as "you may get
unexpected values on inspection" than "even looking invokes UB".


But you're misinterpreting UB.

N869
3. Terms and definitions
3.18
[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements


N1124:

undefined behavior
behavior, upon use of a nonportable or erroneous program construct or
of erroneous data, for which this International Standard imposes no
requirements

indeterminate value
either an unspecified value or a trap representation

unspecified value
valid value of the relevant type where this International Standard
imposes no requirements on which value is chosen in any instance
NOTE An unspecified value cannot be a trap representation.

Jun 27 '06 #25

P: n/a
pete wrote:

Thad Smith wrote:

pete wrote:
The freed pointer value itself is indeterminate.


I expect it to be the same value that it was last assigned.
Why do you think it is indeterminate?


Like Eric Sosman said, because that's what the standard says.

The only possibilties for a pointer value are:
1 null pointer
2 pointer to object
3 pointer to one past object
4 indeterminate

A freed pointer isn't any of the first three.


Unless you're freeing null pointers,
which does happen sometimes.

--
pete
Jun 27 '06 #26

P: n/a

Harald van Dijk wrote:
pete wrote:
Vladimir Oka wrote:
Hmm. The Standard obviously makes a difference between UB and
`indeterminate` value,


Using one causes the other.
I'm inclined to interpret "indeterminate" more as "you may get
unexpected values on inspection" than "even looking invokes UB".


But you're misinterpreting UB.

N869
3. Terms and definitions
3.18
[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements


N1124:

undefined behavior
behavior, upon use of a nonportable or erroneous program construct or
of erroneous data, for which this International Standard imposes no
requirements

indeterminate value
either an unspecified value or a trap representation

unspecified value
valid value of the relevant type where this International Standard
imposes no requirements on which value is chosen in any instance
NOTE An unspecified value cannot be a trap representation.


Ah, so the rules change! In C99 it's not UB, but before it was.
Interesting.

(PS I'm not advocating use indeterminate values.)

Jun 27 '06 #27

P: n/a
=?utf-8?B?SGFyYWxkIHZhbiBExLNr?= wrote:

pete wrote:
Vladimir Oka wrote:
Hmm. The Standard obviously makes a difference between UB and
`indeterminate` value,


Using one causes the other.
I'm inclined to interpret "indeterminate" more as "you may get
unexpected values on inspection" than "even looking invokes UB".


But you're misinterpreting UB.

N869
3. Terms and definitions
3.18
[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements


N1124:

undefined behavior
behavior, upon use of a nonportable or erroneous program construct or
of erroneous data, for which this International Standard imposes no
requirements

indeterminate value
either an unspecified value or a trap representation

unspecified value
valid value of the relevant type where this International Standard
imposes no requirements on which value is chosen in any instance
NOTE An unspecified value cannot be a trap representation.


OK. It's undefined in C89.

ISO/IEC 9899: 1990

3 Definitions and conventions

3.16 undefined behavior:
Behavior, upon use of a nonportable or erroneous program construct,
of erroneous data, or of indeterminately valued objects,
for which this International Standard imposes no requirements.

--
pete
Jun 27 '06 #28

P: n/a
Vladimir Oka wrote:
Harald van Dijk wrote:
pete wrote:
Vladimir Oka wrote:

> Hmm. The Standard obviously makes a difference between UB and
> `indeterminate` value,

Using one causes the other.

> I'm inclined to interpret "indeterminate" more as "you may get
> unexpected values on inspection" than "even looking invokes UB".

But you're misinterpreting UB.

N869
3. Terms and definitions
3.18
[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements
N1124:

undefined behavior
behavior, upon use of a nonportable or erroneous program construct or
of erroneous data, for which this International Standard imposes no
requirements

indeterminate value
either an unspecified value or a trap representation

unspecified value
valid value of the relevant type where this International Standard
imposes no requirements on which value is chosen in any instance
NOTE An unspecified value cannot be a trap representation.


Ah, so the rules change! In C99 it's not UB, but before it was.
Interesting.


To clarify: it's still undefined behaviour if pointer types have trap
representations on your implementation, since even reading trap
representations has undefined behaviour. If all bit patterns represent
valid pointer values in all cases, though, there's no UB in C99.
(PS I'm not advocating use indeterminate values.)


Good idea :)

Jun 27 '06 #29

P: n/a
Vladimir Oka wrote:
Keith Thompson wrote:
"Vladimir Oka" <no****@btopenworld.com> writes:
sp****@gmail.com wrote:
Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?
Probably, as "%p" requires `void *`. ;-)

If you fix that (by casting to `void *`), I don't think it is.
Trying to print `*p` would be though (with "%d", obviously).

It's the dereferencing the dud pointer that causes UB, not accessing
it's value.

Yes, it's undefined behavior. As I mentioned elsethread, C99 6.2.4p2
says:

The value of a pointer becomes indeterminate when the object it
points to reaches the end of its lifetime.

You're very likely to get away with this, but any attempt to even look
at the value of an indeterminate pointer invokes undefined behavior.


Hmm. The Standard obviously makes a difference between UB and
`indeterminate` value, as the sentence just before the one you quote
explicitely says that trying to refer to an object after its lifetime
ends invokes UB (to losely paraphrase). The whole paragraph is:

The lifetime of an object is the portion of program execution during
which
storage is guaranteed to be reserved for it. An object exists, has a
constant
address, and retains its last-stored value throughout its lifetime.
If an object
is referred to outside of its lifetime, the behavior is undefined.
The value of a
pointer becomes indeterminate when the object it points to reaches
the end
of its lifetime.

I'm inclined to interpret "indeterminate" more as "you may get
unexpected values on inspection" than "even looking invokes UB".
Probably something along the lines of Schroedinger's cat (apologies for
likely misspelling of the great man's name).


See my previous response. An indeterminate value is explicitly defined
as being allowed to be a trap representation. Reading a trap
representation invokes undefined behaviour. So, IMHO, it is
conditionally UB. It is UB if the pointer value becomes a trap
representation (which it is allowed to) but not if it becomes an
unspecified value. Interestingly, if it becomes an unspecified value it
*could* compare equal to a valid pointer...

Of course, since there is no way to determine in advance whether you
will get UB or not you effectively have UB.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
Jun 27 '06 #30

P: n/a
sp****@gmail.com wrote:

Consider the following programme:

#include <stdio.h>

int *p ;

void foo(void) {
int a ;

p = &a ;
}

int main() {

foo() ;
printf("p is %p\n",p) ;
}

Is this undefined behaviour ?


Yes, for two reasons. For one thing, it uses the "%p"
specifier with an `int*' argument instead of the required
`void*'. Even before that, though, it tries to use the value
of `p' (it must evaluate `p' as part of the printf() function
call), and the value of `p' is indeterminate because `a' no
longer exists.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jun 27 '06 #31

P: n/a
Reddy wrote:
Thank you all for your responses...


Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the other 99% of the posts in this
group or <http://www.caliburn.nl/topposting.html (thanks Keith).


Brian
Jun 27 '06 #32

P: n/a

Harald van Dijk wrote:
Keith Thompson wrote:
I would expect, in most implementations, that the pointer passed to
free() will retain its previous representation (it's been argued that
this is required),

The standard explicitly allows representations to change during writes,
but not explicitly during reads, and since every object can be accessed
as an array of unsigned char, where each element is itself an object
which must "[retain] its last-stored value throughout its lifetime", I
would've thought this is required.

However, according to
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_260.htm
it is not. I'm not sure what to say about it, though, other than that
another part of the response already directly contradicts the standard:

"If two objects have identical bit-pattern representations and their
types are the same they may still compare as unequal [...]"

6.2.6.1#4: "Two values (other than NaNs) with the same object
representation compare equal,"

"[...] (for example if one object has an indeterminate value) and if
one is an indeterminate value attempting to read such an object invokes
undefined behavior."

If either is an indeterminate value, the behaviour is undefined before
any comparison is made. This means indeterminate values are not an
example of the above.
The response to DR260 is misguided. First of all it
doesn't make clear what's allowed and what's not
allowed. More important though is the problem that
what's allowed depends on some wild and unexplained
inner workings of the compiler (some compiler? the DR
is quite nonspecific).

The C community, compiler writers included, would be
better served if the misguided notion of "provenance"
were completely stricken. Pointer variables have
out-of-band information that affects how they behave
(namely whether the address is valid or not). But
a value is a value is a value, and the same value
must carry the same behavior if we don't want to
fall into the pit of letting compilers define the
language.

Jul 17 '06 #33

P: n/a

pete wrote:
Thad Smith wrote:

pete wrote:
Keith Thompson wrote:
>
>>free() doesn't clear memory; it deallocated it (i.e., makes it
>>available for later allocation). The contents of the memory are
>>indeterminate.
>
The freed pointer value itself is indeterminate.
I expect it to be the same value that it was last assigned.
Why do you think it is indeterminate?

Like Eric Sosman said, because that's what the standard says.

The only possibilties for a pointer value are:
1 null pointer
2 pointer to object
3 pointer to one past object
4 indeterminate

A freed pointer isn't any of the first three.
Does the Standard say anything about what
happens to a pointer one past an object that
has been deallocated? Just curious.

Jul 17 '06 #34

This discussion thread is closed

Replies have been disabled for this discussion.