what malloc(0) should returns?

Q

quiberon2

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 ?
 
R

Richard Heathfield

(e-mail address removed) 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.
 
C

Christopher Benson-Manica

In said:
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.
 
J

Jack Klein

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

David T. Ashley

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

Laurent Deniau

David said:
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.
 
R

Richard Heathfield

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

CBFalconer

Richard said:
David T. Ashley said:


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/>
 
K

Keith Thompson

Richard Heathfield said:
David T. Ashley said:

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

Ben Pfaff

Keith Thompson said:
Richard Heathfield said:
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.)
 
S

Stephen Sprunk

Keith Thompson said:
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
 
K

Keith Thompson

Stephen Sprunk said:
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"?
 
R

Random832

2006-12-18 said:
Keith Thompson said:
Richard Heathfield said:
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]
 
S

Simon Biber

è’‹å®‰å‹ said:
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。请ä¸è¦ä¸Šé¢å›žä¿¡ã€‚那就是在回信时把你写的信全部放在
å‘信者写的信上é¢ã€‚我们这里较喜欢中间回信,那就是在æ¯ä¸€ä¸ªä½ æƒ³å›žç­”的段è½ä¸‹
é¢å†™å…¥ä½ çš„答辩。
 
K

Keith Thompson

Random832 said:
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)".
 
B

Ben Pfaff

Random832 said:
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.

(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>
 
C

CBFalconer

Keith said:
.... snip ...

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

Bill Medland

Keith said:
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)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,121
Latest member
LowellMcGu
Top