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

what malloc(0) should returns?

P: n/a
Hi,
Sorry if it might be a stupid question but what should returns
malloc(0) ?

void *ptr = malloc(0);

I am running gcc 3.3.5 and a non-null address is returned.

( in the compiler that I am currently implementing, NULL is returned.
Is it wrong ?)

or does an address should be always returned and
correspond to the current heap pointer ?

Dec 18 '06 #1
Share this Question
Share on Google+
82 Replies


P: n/a
qu*******@yahoo.com said:
Hi,
Sorry if it might be a stupid question but what should returns
malloc(0) ?

void *ptr = malloc(0);
It's allowed to return NULL, and it's allowed to return a non-NULL pointer
you can't dereference. Both ways are sanctioned by the Standard.

Be careful, though - at least one implementation (C/370) used to (and may
still) be non-conforming for malloc(0) - the program would abend on such a
call.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 18 '06 #2

P: n/a
In comp.lang.c qu*******@yahoo.com wrote:
Sorry if it might be a stupid question but what should returns
malloc(0) ?
7.20.3 (n869):

If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that the
returned pointer shall not be used to access an object.
I am running gcc 3.3.5 and a non-null address is returned.
As it is allowed to do.
( in the compiler that I am currently implementing, NULL is returned.
Is it wrong ?)
No.

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Dec 18 '06 #3

P: n/a
On 18 Dec 2006 07:20:53 -0800, qu*******@yahoo.com wrote in
comp.lang.c:
Hi,
Sorry if it might be a stupid question but what should returns
malloc(0) ?

void *ptr = malloc(0);

I am running gcc 3.3.5 and a non-null address is returned.

( in the compiler that I am currently implementing, NULL is returned.
Is it wrong ?)

or does an address should be always returned and
correspond to the current heap pointer ?
Section 7.20.3 of the current C standard states in part:

"If the size of the space requested is zero, the behavior is
implementation defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that the
returned pointer shall not be used to access an object."

So either behavior is correct, but your compiler's documentation needs
to document which choice it makes.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Dec 18 '06 #4

P: n/a
<qu*******@yahoo.comwrote in message
news:11**********************@48g2000cwx.googlegro ups.com...
>
Sorry if it might be a stupid question but what should returns
malloc(0) ?
I tried it on my Linux system:

[dashley@pamc ~]$ cat malloc_test.c;./a.out
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(0);

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

0x9f5a008

To me personally it makes more sense if malloc(0) returns non-NULL to keep
consistency with realloc()'s behavior with 0.

Interesting thread. I did not know this was implementation-dependent.

Dec 18 '06 #5

P: n/a
qu*******@yahoo.com writes:
Sorry if it might be a stupid question but what should returns
malloc(0) ?
It may return a null pointer or a unique non-null pointer.
--
Peter Seebach on C99:
"[F]or the most part, features were added, not removed. This sounds
great until you try to carry a full-sized printout of the standard
around for a day."
Dec 18 '06 #6

P: n/a
David T. Ashley wrote:
<qu*******@yahoo.comwrote in message
news:11**********************@48g2000cwx.googlegro ups.com...
>>Sorry if it might be a stupid question but what should returns
malloc(0) ?


I tried it on my Linux system:

[dashley@pamc ~]$ cat malloc_test.c;./a.out
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(0);

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

0x9f5a008

To me personally it makes more sense if malloc(0) returns non-NULL to keep
consistency with realloc()'s behavior with 0.
realloc on a null pointer must behave like malloc. So it is also
consistent if malloc(0) returns a null pointer.

a+, ld.
Dec 18 '06 #7

P: n/a
David T. Ashley said:
I did not know this was implementation-dependent.
It's stricter than that. It's not just implementation-dependent, but
implementation-defined. That means that the implementation's documentation
must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc function if the
size requested is zero

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.
+++

I can't find Borland's IDB docs right now. Probably lurking in a cupboard
somewhere. Nor was I successful in tracking down the corresponding docs for
glibc. (sigh)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 18 '06 #8

P: n/a
Richard Heathfield wrote:
David T. Ashley said:
>I did not know this was implementation-dependent.

It's stricter than that. It's not just implementation-dependent,
but implementation-defined. That means that the implementation's
documentation must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc
function if the size requested is zero

The calloc, malloc, and realloc functions accept zero as an
argument. No actual memory is allocated, but a valid pointer is
returned and the memory block can be modified later by realloc.
+++

I can't find Borland's IDB docs right now. Probably lurking in a
cupboard somewhere. Nor was I successful in tracking down the
corresponding docs for glibc. (sigh)
That provision leads to problems in detecting run-time allocation
errors without all sorts of special wrappers. For this (and other)
reasons I designed my nmalloc [1] to always return a valid
pointer. This is done by simply insisting on allocating at least
one byte. I don't like the idea of:

void *xgetmem(size_t sz) {
void *p;
if (NULL == (p = malloc(sz))) exit(EXIT_FAILURE);
return p;
}

aborting when called with the argument 0. I think reserving NULL
returns for real failures is a QofI matter. In this case I think
Microsoft actually did the right thing.

[1] <http://cbfalconer.home.att.net/download/>

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 18 '06 #9

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
David T. Ashley said:
>I did not know this was implementation-dependent.

It's stricter than that. It's not just implementation-dependent, but
implementation-defined. That means that the implementation's documentation
must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc function if the
size requested is zero

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.
I wonder how it manages to return a valid pointer without allocating
any actual memory. Based on the wording of the standard, I would
expect successive calls to malloc(0) (assuming it doesn't return a
null pointer value) to return distinct values.

--
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.
Dec 18 '06 #10

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Richard Heathfield <rj*@see.sig.invalidwrites:
>For example, Microsoft's C compiler documentation says:

+++
The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. [...]
Some systems have a class of pointers that can't be dereferenced
but won't trap. For example, under Linux on x86 you could
normally use any pointer with value 0xc0000000 (as seen when cast
to uintptr_t) or greater as such. As long as you didn't need
more than about a billion of them, you could just use a counter
to keep track of how many you'd given out. Once you ran out, you
could fall back to treating malloc(0) as malloc(1) or just
returning a null pointer.

(I don't know how Linux system calls would react to such a
pointer. Probably unhappily.)
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
Dec 18 '06 #11

P: n/a
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Richard Heathfield <rj*@see.sig.invalidwrites:
>The calloc, malloc, and realloc functions accept zero as an argument.
No actual memory is allocated, but a valid pointer is returned and
the
memory block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. Based on the wording of the standard, I would
expect successive calls to malloc(0) (assuming it doesn't return a
null pointer value) to return distinct values.
A common implementation of malloc() writes a header (containing links
between blocks, size of the user object, and possibly a magic value to
detect corruption) regardless of allocation size. The value returned to
the user is the address *after* the header.

In the case of malloc(0), the header is immediately followed by the next
header (or a trailer with a magic value to detect corruption, then the
next header). Therefore, successive calls will return different
addresses, since each new header starts at a different address. Do it
enough times and you can run out of heap space even though you're
theoretically allocating no memory :)

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
--
Posted via a free Usenet account from http://www.teranews.com

Dec 18 '06 #12

P: n/a
"Stephen Sprunk" <st*****@sprunk.orgwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>The calloc, malloc, and realloc functions accept zero as an argument.
No actual memory is allocated, but a valid pointer is returned and
the
memory block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. Based on the wording of the standard, I would
expect successive calls to malloc(0) (assuming it doesn't return a
null pointer value) to return distinct values.

A common implementation of malloc() writes a header (containing links
between blocks, size of the user object, and possibly a magic value to
detect corruption) regardless of allocation size. The value returned
to the user is the address *after* the header.

In the case of malloc(0), the header is immediately followed by the
next header (or a trailer with a magic value to detect corruption,
then the next header). Therefore, successive calls will return
different addresses, since each new header starts at a different
address. Do it enough times and you can run out of heap space even
though you're theoretically allocating no memory :)
So the memory allocated for the header isn't "actual memory"?

--
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.
Dec 19 '06 #13

P: n/a


On Mon, 18 Dec 2006, Keith Thompson wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
>David T. Ashley said:
<snipped>
>For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc function if the
size requested is zero

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory.
Such thing is possible in Windows using the VirtualAlloc() Win32 API
function, if the MEM_RESERVE flag is passed to it.

See its complete description at:

http://msdn.microsoft.com/library/de...rtualalloc.asp
Emil
<snipped>
Dec 19 '06 #14

P: n/a
2006-12-18 <87************@blp.benpfaff.org>,
Ben Pfaff wrote:
Keith Thompson <ks***@mib.orgwrites:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>For example, Microsoft's C compiler documentation says:

+++
The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. [...]

Some systems have a class of pointers that can't be dereferenced
but won't trap. For example, under Linux on x86 you could
normally use any pointer with value 0xc0000000 (as seen when cast
to uintptr_t) or greater as such. As long as you didn't need
more than about a billion of them, you could just use a counter
to keep track of how many you'd given out. Once you ran out, you
could fall back to treating malloc(0) as malloc(1) or just
returning a null pointer.
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.
(I don't know how Linux system calls would react to such a
pointer. Probably unhappily.)
Standard procedure on receiving an invalid pointer is to return -EINVAL
[which the library changes to an appropriate failure return and errno
EINVAL]
Dec 19 '06 #15

P: n/a
Random832 <ra****@random.yi.orgwrites:
[...]
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.
A quick test of a few systems I happen to have immediate access to
shows that all of them either return a null pointer, or return
distinct values on two successive calls to malloc(0).

As for why this is required, C99 7.20.3p1 says:

If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that
the returned pointer shall not be used to access an object.

One aspect of the behavior of malloc() with a non-zero size is that
successive calls return unique values. My interpretation is that this
same behavior is required for non-null results of malloc(0).

The simplest way to implement this is to quietly translate "malloc(0)"
to "malloc(1)".

--
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.
Dec 19 '06 #16

P: n/a
Random832 <ra****@random.yi.orgwrites:
2006-12-18 <87************@blp.benpfaff.org>,
Ben Pfaff wrote:
>Some systems have a class of pointers that can't be dereferenced
but won't trap. For example, under Linux on x86 you could
normally use any pointer with value 0xc0000000 (as seen when cast
to uintptr_t) or greater as such. As long as you didn't need
more than about a billion of them, you could just use a counter
to keep track of how many you'd given out. Once you ran out, you
could fall back to treating malloc(0) as malloc(1) or just
returning a null pointer.

I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.
They'd better not do that (C99 7.20.3):

If the size of the space requested is zero, the behavior is
implementation- defined: either a null pointer is returned,
or the behavior is as if the size were some nonzero value,
except that the returned pointer shall not be used to access
an object.

<off-topic xmlns="news:comp.lang.c">
>(I don't know how Linux system calls would react to such a
pointer. Probably unhappily.)

Standard procedure on receiving an invalid pointer is to return -EINVAL
[which the library changes to an appropriate failure return and errno
EINVAL]
That's definitely not correct: EFAULT is the POSIX error code for
"bad address". But the question is whether the kernel pays
attention to the pointer value if the associated length is 0. It
might, or it might not, or it might differ from one system call
to another.
</off-topic>
--
"Programmers have the right to be ignorant of many details of your code
and still make reasonable changes."
--Kernighan and Plauger, _Software Tools_
Dec 19 '06 #17

P: n/a
蒋安友 wrote:
Hi,
<HEAD>
What should malloc(0) do? Return a null pointer or a pointer to
0 bytes?
</HEAD>
Welcome to comp.lang.c. Please don't top-post. We prefer inline replying
here. See Posting Styles at Wikipedia:

http://en.wikipedia.org/wiki/Posting_styles

欢迎您来到comp.lang.c。请不要上面回信 。那就是在回信时把*写的信全部放
发信者写的信上面。我们这里较喜欢 *间回信,那就是在每一个*想回*的 落下
面写入*的*辩。

--
Simon.
Dec 19 '06 #18

P: n/a
Keith Thompson wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
>David T. Ashley said:
>>I did not know this was implementation-dependent.

It's stricter than that. It's not just implementation-dependent, but
implementation-defined. That means that the implementation's
documentation must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc function if
the size requested is zero

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the
memory block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. Based on the wording of the standard, I would
expect successive calls to malloc(0) (assuming it doesn't return a
null pointer value) to return distinct values.
Well, I expect it frequently does allocate memory; it presumably just
allocates enough for its own management purposes rather than what it needs
and what the caller wants (and the text is the usual user-intended
Microsoft text rather than the pedantic version)

--
Bill Medland
Dec 19 '06 #19

P: n/a
Bill Medland <bi*********@shaw.cawrites:
Keith Thompson wrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>David T. Ashley said:
I did not know this was implementation-dependent.

It's stricter than that. It's not just implementation-dependent, but
implementation-defined. That means that the implementation's
documentation must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc function if
the size requested is zero

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the
memory block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. Based on the wording of the standard, I would
expect successive calls to malloc(0) (assuming it doesn't return a
null pointer value) to return distinct values.

Well, I expect it frequently does allocate memory; it presumably just
allocates enough for its own management purposes rather than what it needs
and what the caller wants (and the text is the usual user-intended
Microsoft text rather than the pedantic version)
Or it allocates a unique (and invalid) address without allocating any
memory at that address. free() might then require an extra test to
detect the implementation-defined pointers returned by malloc(0).

--
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.
Dec 19 '06 #20

P: n/a
Keith Thompson wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
.... snip ...
>>
For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc
function if the size requested is zero

The calloc, malloc, and realloc functions accept zero as an
argument. No actual memory is allocated, but a valid pointer is
returned and the memory block can be modified later by realloc.

I wonder how it manages to return a valid pointer without
allocating any actual memory. Based on the wording of the
standard, I would expect successive calls to malloc(0) (assuming
it doesn't return a null pointer value) to return distinct values.
Note it doesn't say no memory is consumed, just none is allocated.
I could say the same about nmalloc. As far as the user is
concerned he asked for, and got, zero bytes.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 19 '06 #21

P: n/a
Random832 wrote:
>
.... snip ...
>
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.
p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if (p1 ==
p2)".

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 19 '06 #22

P: n/a
On Tue, 19 Dec 2006 01:06:08 GMT, Keith Thompson <ks***@mib.orgwrote
in comp.lang.c:
Random832 <ra****@random.yi.orgwrites:
[...]
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

A quick test of a few systems I happen to have immediate access to
shows that all of them either return a null pointer, or return
distinct values on two successive calls to malloc(0).

As for why this is required, C99 7.20.3p1 says:

If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that
the returned pointer shall not be used to access an object.

One aspect of the behavior of malloc() with a non-zero size is that
successive calls return unique values. My interpretation is that this
same behavior is required for non-null results of malloc(0).
Do you have a standard citation for that?

Is there any reason why, in a suitable function with a suitable
implementation and suitable includes:

uintptr_t pu, qu;
void *p = malloc(100);
pu = (uintptr_t)p;
free (p);
p = malloc(100);
qu = (uintptr_t)p;
if (pu == qu)
do_something();
else
do_something_else();

....are you claiming that pu and qu must compare unequal because they
were returned by successive calls to malloc()?

Any program that depends on malloc() never returning the same pointer
twice, especially with intervening calls to free(), is broken.
The simplest way to implement this is to quietly translate "malloc(0)"
to "malloc(1)".
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Dec 19 '06 #23

P: n/a
Jack Klein <ja*******@spamcop.netwrites:
On Tue, 19 Dec 2006 01:06:08 GMT, Keith Thompson <ks***@mib.orgwrote
in comp.lang.c:
>Random832 <ra****@random.yi.orgwrites:
[...]
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

A quick test of a few systems I happen to have immediate access to
shows that all of them either return a null pointer, or return
distinct values on two successive calls to malloc(0).

As for why this is required, C99 7.20.3p1 says:

If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that
the returned pointer shall not be used to access an object.

One aspect of the behavior of malloc() with a non-zero size is that
successive calls return unique values. My interpretation is that this
same behavior is required for non-null results of malloc(0).

Do you have a standard citation for that?
Um, C99 7.20.3p1?
Is there any reason why, in a suitable function with a suitable
implementation and suitable includes:

uintptr_t pu, qu;
void *p = malloc(100);
pu = (uintptr_t)p;
free (p);
p = malloc(100);
qu = (uintptr_t)p;
if (pu == qu)
do_something();
else
do_something_else();

...are you claiming that pu and qu must compare unequal because they
were returned by successive calls to malloc()?
Yes, I am.
Any program that depends on malloc() never returning the same pointer
twice, especially with intervening calls to free(), is broken.
Multiple calls to malloc() with non-zero arguments, assuming they all
succeed, must return distinct pointers, assuming there are no
intervening calls to free().

If malloc(0) returns a non-null result, then it must behave as if it
were called with a non-zero argument; it seems to me that means
returning distinct values.

On the other hand, a portable application can't depend on malloc(0)
returning a non-null result anyway, so the guarantee doesn't do much
good.

--
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.
Dec 19 '06 #24

P: n/a
On Mon, 18 Dec 2006 16:29:02 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
>David T. Ashley said:
>I did not know this was implementation-dependent.

It's stricter than that. It's not just implementation-dependent, but
implementation-defined. That means that the implementation's documentation
must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

+++
C Language Reference
Allocating Zero Memory

ANSI 4.10.3 The behavior of the calloc, malloc, or realloc function if the
size requested is zero

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.
+++
In the same compiler documentation, further clarification is given:

<quote>
malloc

void *malloc( size_t size );
....
If size is 0, malloc allocates a zero-length item in the heap and
returns a valid pointer to that item. Always check the return from
malloc, even if the amount of memory requested is small.
</quote>

This compiler documentation uses a non-standard,
implementation-specific term such as "heap" to further "clarify"
things (The concept of a "heap" is second hand news to any serious
developer for the WIN32 platform).

The last sentence in the above quote is meant for your own good, and
has nothing to do with how the OS might misbehave (though it could).
All WIN32 platforms--95/98/ME/NT/2K/XP/2003/Vista/32/64--gracefully
handle null pointer dereferences.

Thanks Microsoft
--
jay
Dec 19 '06 #25

P: n/a
CBFalconer wrote:
Random832 wrote:
>>
... snip ...
>>
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if (p1 ==
p2)".
If an implementation chose to return
the same pointer P for each malloc(0)
then realloc would need to know
that P was operationally equal
to null, and hence in your code above
the realloc would just mallocate
100 bytes for your convenience.

Wouldn't it?

--
Chris "HO. HO. HO." Dollin
"It took a very long time, much longer than the most generous estimates."
- James White, /Sector General/

Dec 19 '06 #26

P: n/a
Chris Dollin <ch**********@hp.comwrote:
CBFalconer wrote:
Random832 wrote:
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.
p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if (p1 ==
p2)".

If an implementation chose to return the same pointer P for each malloc(0)
then realloc would need to know that P was operationally equal
to null, and hence in your code above the realloc would just mallocate
100 bytes for your convenience.
Ok, now try this one:

char *p1, *p2;
p1=malloc(0); p2=malloc(0);
p1=realloc(p1, 200);
p2=realloc(p2, 100);
p1[123]='?';

If subsequent (non-free()d) calls to malloc(0) were allowed to deliver
identical pointers, that code would be allowed to make flying reindeer
come out of the North Pole. But Santa is just a cheap copy of the real,
Dutch, Saint Nicholas, and that code (bad use of realloc() excepted)
does not have undefined behaviour. Therefore, all pointers returned from
malloc(0) must be either null or not equal to any other pointer,
including ones obtained from other calls to malloc(0).

Richard
Dec 19 '06 #27

P: n/a
Richard Bos wrote:
Chris Dollin <ch**********@hp.comwrote:
>CBFalconer wrote:
Random832 wrote:

I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if (p1 ==
p2)".

If an implementation chose to return the same pointer P for each malloc(0)
then realloc would need to know that P was operationally equal
to null, and hence in your code above the realloc would just mallocate
100 bytes for your convenience.

Ok, now try this one:

char *p1, *p2;
p1=malloc(0); p2=malloc(0);
p1=realloc(p1, 200);
p2=realloc(p2, 100);
p1[123]='?';

If subsequent (non-free()d) calls to malloc(0) were allowed to deliver
identical pointers, that code would be allowed to make flying reindeer
come out of the North Pole. But Santa is just a cheap copy of the real,
Dutch, Saint Nicholas, and that code (bad use of realloc() excepted)
does not have undefined behaviour. Therefore, all pointers returned from
malloc(0) must be either null or not equal to any other pointer,
including ones obtained from other calls to malloc(0).
I don't know if it's your metaphor or the imminent arrival of the
holiday or what, but I can't see why your example poses a problem
to the tactic in my remark above. Could you unpack?

--
Chris "HO. HO. HO." Dollin
"Who do you serve, and who do you trust?" /Crusade/

Dec 19 '06 #28

P: n/a
Chris Dollin wrote:
CBFalconer wrote:
>Random832 wrote:
>>>
... snip ...
>>>
I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if
(p1 == p2)".

If an implementation chose to return the same pointer P for each
malloc(0) then realloc would need to know that P was operationally
equal to null, and hence in your code above the realloc would just
mallocate 100 bytes for your convenience.
No reason for that complication. It isn't required by the
standard. The following (from N869) is adequate:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
not be used to access an object. The value of a pointer
that refers to freed space is indeterminate.

Note that a freed pointer DOES NOT point to an object.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 19 '06 #29

P: n/a
CBFalconer wrote:
Chris Dollin wrote:
>CBFalconer wrote:
>>Random832 wrote:

... snip ...

I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if
(p1 == p2)".

If an implementation chose to return the same pointer P for each
malloc(0) then realloc would need to know that P was operationally
equal to null, and hence in your code above the realloc would just
mallocate 100 bytes for your convenience.

No reason for that complication. It isn't required by the
standard. The following (from N869) is adequate:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
not be used to access an object. The value of a pointer
that refers to freed space is indeterminate.

Note that a freed pointer DOES NOT point to an object.
You're arguing that the standard says that multiple malloc(0)s
shall not re-use the same pointer value, yes? That's fine
then.

If it /didn't/ explicitly forbid it, then I don't see that
there would be a problem. Other posters (eg Random832) seemed
to be arguing that there would.

I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.

--
Chris "HO. HO. HO." Dollin
"Who do you serve, and who do you trust?" /Crusade/

Dec 19 '06 #30

P: n/a
trm
Keith Thompson schrieb:
Jack Klein <ja*******@spamcop.netwrites:
Is there any reason why, in a suitable function with a
suitable implementation and suitable includes:

uintptr_t pu, qu;
void *p = malloc(100);
pu = (uintptr_t)p;
free (p);
^^^^^^^^
p = malloc(100);
qu = (uintptr_t)p;
if (pu == qu)
do_something();
else
do_something_else();

...are you claiming that pu and qu must compare unequal
because they were returned by successive calls to malloc()?

Yes, I am.
Er, I suspect this would break a lot of code...
Any program that depends on malloc() never returning the
same pointer twice, especially with intervening calls to
free(), is broken.

Multiple calls to malloc() with non-zero arguments, assuming
they all succeed, must return distinct pointers, assuming
there are no intervening calls to free().
....I believe you may have misspelled "No, I'm not" up above.
Would you mind clarifying your clarification?

Dec 19 '06 #31

P: n/a
Chris Dollin wrote:
>
CBFalconer wrote:
Chris Dollin wrote:
CBFalconer wrote:
Random832 wrote:

... snip ...

I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.

p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if
(p1 == p2)".

If an implementation chose to return the same pointer P for each
malloc(0) then realloc would need to know that P was operationally
equal to null, and hence in your code above the realloc would just
mallocate 100 bytes for your convenience.
No reason for that complication. It isn't required by the
standard. The following (from N869) is adequate:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
not be used to access an object. The value of a pointer
that refers to freed space is indeterminate.

Note that a freed pointer DOES NOT point to an object.

You're arguing that the standard says that multiple malloc(0)s
shall not re-use the same pointer value, yes? That's fine
then.

If it /didn't/ explicitly forbid it, then I don't see that
there would be a problem. Other posters (eg Random832) seemed
to be arguing that there would.

I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.
No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 19 '06 #32

P: n/a
CBFalconer wrote:
Chris Dollin wrote:
>I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.

No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.
I'm thinking, but I can't see an anomaly. I'm probably just being
dim.

--
Chris "HO. HO. HO." Dollin
Meaning precedes definition.

Dec 19 '06 #33

P: n/a
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
"Stephen Sprunk" <st*****@sprunk.orgwrites:
>"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>>Richard Heathfield <rj*@see.sig.invalidwrites:
The calloc, malloc, and realloc functions accept zero as an
argument.
No actual memory is allocated, but a valid pointer is returned and
the
memory block can be modified later by realloc.

I wonder how it manages to return a valid pointer without allocating
any actual memory. Based on the wording of the standard, I would
expect successive calls to malloc(0) (assuming it doesn't return a
null pointer value) to return distinct values.

A common implementation of malloc() writes a header (containing links
between blocks, size of the user object, and possibly a magic value
to
detect corruption) regardless of allocation size. The value returned
to the user is the address *after* the header.

In the case of malloc(0), the header is immediately followed by the
next header (or a trailer with a magic value to detect corruption,
then the next header). Therefore, successive calls will return
different addresses, since each new header starts at a different
address. Do it enough times and you can run out of heap space even
though you're theoretically allocating no memory :)

So the memory allocated for the header isn't "actual memory"?
It depends on your perspective. Since malloc() returns an address
*after* the header, user code cannot legally access the header since
it's not part of the object returned from malloc(). It's not "actual
memory" to C user code. You asked for a zero-byte object, and you got a
zero-byte object, so in theory you've allocated zero bytes.

OTOH, it's certainly "actual memory" to the implementation, since
malloc() does need to request memory from the OS (or wherever) to store
the header, but that header isn't part of a C object as far as user code
can tell.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
--
Posted via a free Usenet account from http://www.teranews.com

Dec 19 '06 #34

P: n/a
Keith Thompson wrote:
>
Jack Klein <ja*******@spamcop.netwrites:
.... snip ...
>>
uintptr_t pu, qu;
void *p = malloc(100);
pu = (uintptr_t)p;
free (p);
p = malloc(100);
qu = (uintptr_t)p;
if (pu == qu)
do_something();
else
do_something_else();

...are you claiming that pu and qu must compare unequal because
they were returned by successive calls to malloc()?

Yes, I am.
Not so. The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.

--
If you want to post a followup via groups.google.com, ensure
you quote enough for the article to make sense. Google is only
a poor interface to usenet. There is no reason to assume your
readers can, or ever will, see any previous articles.
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Dec 19 '06 #35

P: n/a
CBFalconer wrote:
Random832 wrote:

... snip ...
>>I think typically systems (at least, UNIX systems) that don't return
NULL return the same printer every time. It's not really clear why
they'd have to be different.


p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if (p1 ==
p2)".
But p2 could also be changed. E.g. malloc and free could be

void *malloc (size_t n)
{
if (!n)
return (void*) 0xFF0909FF;
else
{
void *result = __get_me_some_memory (n);
assert (result != (void*) 0xFF0909FF);
return result;
}
}

void free (void *ptr)
{
if (ptr && ptr != (void*) 0xFF0909FF)
__free_that_memory (ptr);
}

It doesn't make much sense since standard forbids it, but what would
break if it were like this?
Your example with realloc() assumes implementation returns some sensible
pointer on malloc(0), which can actually point to some memory allocated
later, but it's not necessary.
I believe Keith Thompson's quote is what really matters here, about
non-NULL result of malloc(0) behaving the same as malloc(10) (in
particular, non-NULL pointers must be different), so all this stuff
doesn't matter in practice though :)

Best regards,
Yevgen
Dec 19 '06 #36

P: n/a
2006-12-19 <45***************@yahoo.com>,
CBFalconer wrote:
The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.
In what sense is the non-null result of malloc(0) a pointer to an object
anyway?
Dec 19 '06 #37

P: n/a
Chris Dollin wrote:
CBFalconer wrote:
>Chris Dollin wrote:
>>I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.

No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.

I'm thinking, but I can't see an anomaly. I'm probably just being
dim.
You snipped one that I showed earlier.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 19 '06 #38

P: n/a
>Chris Dollin wrote:
>>I am not arguing that the choice "malloc(0) always returns the
same pointer" would be /sensible/ if it were legal, just that
it could be made to work consistently.
>CBFalconer wrote:
>No it couldn't. Think about pointer comparisons. Then think about
what other anomalies could exist. But one is enough to show it is
a bad idea.
In article <em**********@murdoch.hpl.hp.com>
Chris Dollin <ch**********@hp.comwrote:
>I'm thinking, but I can't see an anomaly. I'm probably just being
dim.
Since malloc() is a reserved function name, let me illustrate with
a different function-name. This also lets me use malloc() for the
"hard parts".

#include <stdlib.h>

static char magic;

void *nalloc(size_t size) {
if (size == 0)
return &magic; /* or: return NULL */
return malloc(size);
}

void nfree(void *p) {
if (p != &magic)
free(p);
}

void nrealloc(void *p, size_t size) {
if (p == &magic)
p = NULL;
if (size == 0) {
free(p);
return &magic; /* or: return NULL */
}
return realloc(p, size);
}

Given the obvious preconditions, the behavior of this code is
well-defined (which may suffice to label it "sensible"), but would
it suffice to replicate the Standard's requirements for malloc()?

I believe the answer is "no":

/* insert appropriate #include lines, etc., as needed */

#define Xalloc nalloc /* or malloc */
#define NAME "nalloc" /* or "malloc" */
#define Xfree nfree /* or free */

void check_it(void) {
void *p1 = Xalloc(0);
void *p2 = Xalloc(0);

if (p1 == NULL && p2 == NULL)
puts("OK: " NAME "(0) returned NULL each time");
else if (p1 == p2)
puts("FAIL: p1 == p2, but p1 and p2 are not NULL");
else {
puts("OK: alloc(0), called twice, returned two different")
puts("non-NULLs, or one non-NULL and one NULL");
}
Xfree(p1);
Xfree(p2);
}

If we use this check_it() routine on nalloc(), it will print the
"FAIL" line, because p1 and p2 are equal, yet at least one of the
two pointers is not NULL (in fact both point to the "magic" byte).

What if we replace the "return &magic" lines with "return NULL"?
Then I believe nalloc() satisfies the requirements for malloc().

Note that if one modifies check_it() -- or rather, the variant of
check_it() that uses malloc() -- to call free() on either p1 or p2
before testing their values, the check_it() function itself becomes
invalid: an attempt to use the value of a non-NULL pointer variable
that was once valid, but has since been passed to free(), causes
undefined behavior (<http://web.torek.net/torek/c/numbers2.html>).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Dec 19 '06 #39

P: n/a
Richard Heathfield wrote:
It's stricter than that. It's not just implementation-dependent, but
implementation-defined. That means that the implementation's documentation
must tell you which choice it made.

For example, Microsoft's C compiler documentation says:

The calloc, malloc, and realloc functions accept zero as an argument. No
actual memory is allocated, but a valid pointer is returned and the memory
block can be modified later by realloc.
Well, the implementation is allowed to return NULL if allocation
failed. So, effectively we have that this implementation may either
return a valid pointer or return NULL in case of malloc(0).

You might say that allocation cannot fail when zero bytes are
requested. However, the standard also says that the pointer
returned should point to the first byte of allocated storage.
So it appears that allocation is required, and therefore, it may fail.

Dec 19 '06 #40

P: n/a

"CBFalconer" <cb********@yahoo.comwrote in message
news:45***************@yahoo.com...
>>...are you claiming that pu and qu must compare unequal because
they were returned by successive calls to malloc()?

Yes, I am.

Not so. The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.
I think keith missed the free because he says later "assuming there are no
intervening calls to free()"
Dec 19 '06 #41

P: n/a
"trm" <tr****@yahoo.comwrites:
Keith Thompson schrieb:
>Jack Klein <ja*******@spamcop.netwrites:
Is there any reason why, in a suitable function with a
suitable implementation and suitable includes:

uintptr_t pu, qu;
void *p = malloc(100);
pu = (uintptr_t)p;
free (p);
^^^^^^^^
p = malloc(100);
qu = (uintptr_t)p;
if (pu == qu)
do_something();
else
do_something_else();

...are you claiming that pu and qu must compare unequal
because they were returned by successive calls to malloc()?

Yes, I am.
And I was wrong.
Er, I suspect this would break a lot of code...
It would break a lot of implementations, but it shouldn't break much
code; well-written code shouldn't *care* about the values of free()d
pointers.
Any program that depends on malloc() never returning the
same pointer twice, especially with intervening calls to
free(), is broken.

Multiple calls to malloc() with non-zero arguments, assuming
they all succeed, must return distinct pointers, assuming
there are no intervening calls to free().

...I believe you may have misspelled "No, I'm not" up above.
Would you mind clarifying your clarification?
I missed the free() call. Certainly an implementation can re-use
free()d addresses.

What I *meant* to assert is that, for example, the following:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *p1 = malloc(0);
void *p2 = malloc(0);
if (p1 == NULL || p2 == NULL || p1 != p2) {
puts("ok");
}
else {
puts("oops");
}
return 0;
}

must always print "ok".

Note that if malloc(0) returns a null pointer, it can be either
because the implementation always does that, or because there's not
enough available memory.

In my opinion, the behavior defined by the standard for malloc(0) is
not particularly useful.

--
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.
Dec 19 '06 #42

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>>
Jack Klein <ja*******@spamcop.netwrites:
... snip ...
>>>
uintptr_t pu, qu;
void *p = malloc(100);
pu = (uintptr_t)p;
free (p);
p = malloc(100);
qu = (uintptr_t)p;
if (pu == qu)
do_something();
else
do_something_else();

...are you claiming that pu and qu must compare unequal because
they were returned by successive calls to malloc()?

Yes, I am.

Not so. The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.
Quite correct; I missed the call to free().

--
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.
Dec 19 '06 #43

P: n/a
Random832 wrote:
CBFalconer wrote:
>The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.

In what sense is the non-null result of malloc(0) a pointer to an
object anyway?
In the sense that it behaves that way. However you can't legally
dereference it, just as you can't alter an anonymous char string.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 19 '06 #44

P: n/a
Yevgen Muntyan wrote:
CBFalconer wrote:
>Random832 wrote:

... snip ...
>>I think typically systems (at least, UNIX systems) that don't
return NULL return the same printer every time. It's not really
clear why they'd have to be different.

p1 = malloc(0); p2 = malloc(0); p2 = realloc(p2, 100);

(Ignore the misuse of realloc). Now, if p2 had free space above
it, p2 might be unchanged. However p1 is still pointing to zero
bytes. You would get very funny results by depending on "if (p1 ==
p2)".

But p2 could also be changed. E.g. malloc and free could be
Please don't send email copies of usenet articles. It is just
further clutter and annoyance at this end.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 19 '06 #45

P: n/a

"jaysome" <ja*****@hotmail.comwrote in message
news:f2********************************@4ax.com...
On Mon, 18 Dec 2006 16:29:02 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
The last sentence in the above quote is meant for your own good, and
has nothing to do with how the OS might misbehave (though it could).
All WIN32 platforms--95/98/ME/NT/2K/XP/2003/Vista/32/64--gracefully
handle null pointer dereferences.
depends if you call access violations graceful ;)
Dec 19 '06 #46

P: n/a
2006-12-19 <45***************@yahoo.com>,
CBFalconer wrote:
Random832 wrote:
>CBFalconer wrote:
>>The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.

In what sense is the non-null result of malloc(0) a pointer to an
object anyway?

In the sense that it behaves that way. However you can't legally
dereference it, just as you can't alter an anonymous char string.
To what object does it point?
Dec 19 '06 #47

P: n/a
Random832 wrote:
2006-12-19 <45***************@yahoo.com>,
CBFalconer wrote:
Random832 wrote:
CBFalconer wrote:

The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.

In what sense is the non-null result of malloc(0) a pointer to an
object anyway?
In the sense that it behaves that way. However you can't legally
dereference it, just as you can't alter an anonymous char string.

To what object does it point?
It doesn't have a name, just as the result of malloc(sizeof(int))
doesn't have a name.

An object is defined as "region of data storage in the execution
environment, the contents of which can represent values". Since
malloc(0) must (if it doesn't return NULL) behave as if a positive
argument is passed, except for dereferencing, you still get a pointer
to a region. In particular, if you convert malloc's result to a
character pointer, it means you're allowed to increment it at least
once. The fact that you're not allowed to access the value is
irrelevant, since the definition doesn't state otherwise.

Dec 19 '06 #48

P: n/a
Harald van D?k wrote:
Random832 wrote:
>CBFalconer wrote:
>>Random832 wrote:
CBFalconer wrote:

The standard requires malloced pointers to objects be
distinct. After the free(p) p is no longer a pointer to an object.

In what sense is the non-null result of malloc(0) a pointer to an
object anyway?

In the sense that it behaves that way. However you can't legally
dereference it, just as you can't alter an anonymous char string.

To what object does it point?

It doesn't have a name, just as the result of malloc(sizeof(int))
doesn't have a name.

An object is defined as "region of data storage in the execution
environment, the contents of which can represent values". Since
malloc(0) must (if it doesn't return NULL) behave as if a positive
argument is passed, except for dereferencing, you still get a pointer
to a region. In particular, if you convert malloc's result to a
character pointer, it means you're allowed to increment it at least
once. The fact that you're not allowed to access the value is
irrelevant, since the definition doesn't state otherwise.
Since it points to zero storage bytes, it has already been
incremented to one past the storage area.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 19 '06 #49

P: n/a
Harald van Dijk wrote:
An object is defined as "region of data storage in the execution
environment, the contents of which can represent values". Since
malloc(0) must (if it doesn't return NULL) behave as if a positive
argument is passed, except for dereferencing, you still get a pointer
to a region. In particular, if you convert malloc's result to a
character pointer, it means you're allowed to increment it at least
once. The fact that you're not allowed to access the value is
irrelevant, since the definition doesn't state otherwise.
Are you sure that you're allowed to increment it? I think that's unclear
from the C standard's wording:

"If the size of the space requested is zero, the behavior is
implementation defined: either a null pointer is returned,
or the behavior is as if the size were some nonzero value,
except that the returned pointer shall not be used to access
an object."

It does not merely say that the returned pointer shall not be
dereferenced. It says that it shall not be used to access an object. If
you convert the pointer to char* and increment it, that action is only
valid if there is an object of at least one byte at the address. So it
could be argued that in effect you have used the pointer to access an
object.

--
Simon.
Dec 19 '06 #50

82 Replies

This discussion thread is closed

Replies have been disabled for this discussion.