[comp.std.c] What does malloc

steve@unidata.ucar.edu (Steve Emmerson) (06/01/91)

Greetings,

The subject-line says it all and my K&R2 is silent on the matter.
Is the answer NULL, non-NULL (but don't dereference), undefined,
or implementation-defined?

Thanks in advance.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

gwyn@smoke.brl.mil (Doug Gwyn) (06/01/91)

In article <11614@ncar.ucar.edu> steve@unidata.ucar.edu (Steve Emmerson) writes:
>The subject-line says it all and my K&R2 is silent on the matter.

malloc(0) should return either NULL or a pointer to some storage location.
Technically the behavior is undefined, since there are no objects of the
specified size (0) according to the standard.

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (06/01/91)

steve@unidata.ucar.edu (Steve Emmerson) writes:

>Greetings,
>
>The subject-line says it all and my K&R2 is silent on the matter.
>Is the answer NULL, non-NULL (but don't dereference), undefined,
>or implementation-defined?

If it did return the address of somewhere in memory, you cannot
dereference that pointer without exceeding the size.

It would be more useful if it did return something consistent like NULL.
Prior to this posting, had I needed to implement malloc(0) I am sure
I would have just implemented it to return NULL in that case unless
I found a reason not to.
-- 
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
 \***************************************************************************/

bhoughto@hopi.intel.com (Blair P. Houghton) (06/01/91)

In article <16317@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <11614@ncar.ucar.edu> steve@unidata.ucar.edu (Steve Emmerson) writes:
>>The subject-line says it all and my K&R2 is silent on the matter.
>
>malloc(0) should return either NULL or a pointer to some storage location.
>Technically the behavior is undefined, since there are no objects of the
>specified size (0) according to the standard.

The memory-allocation functions have an "out" for that semantic:

	"If the size of the space requested is zero, the behavior
	 is implementation-defined; the value returned shall be
	 either a null pointer or a unique pointer."
		 (ANSI X3.159-1989, sec. 4.10.3, p. 155, ll. 18-20)

What it says is that it is guaranteed not to point to any
previously accessible object.  Presumably the rest of your
code is careful enough to keep track of the amount of space
it has requested and react correctly if the space is
zero-sized.

But, the pointer, if it is returned, points to an address
which is correctly aligned for _any_ object.  Whether this
has any use I do not know.  However, it does mean that
malloc() may not again return that pointer (not without
free()ing it first), which means it can't use that
alignment, which means the next time it's called it may
return a pointer to the next aligned space in
its managed list.  I.e., `malloc(0)' must "eat" space if it
does not return NULL, though that space is not necessarily
allocated (although this goes out the window if your computer
is capable of implementing pointers that refer to aligned
space that does not exist; e.g., in the case where alignment
is irrelevant and pointers are doubly-indirect...)

Moral:  if you anticipate asking for nonpositive numbers of
chars from malloc(), check the size before calling malloc,
because malloc()'s return-value does not give any hint how
much space you asked for, even if you asked for no space.

				--Blair
				  "Cranial capacity jokes to /dev/malloc(0)"

gwyn@smoke.brl.mil (Doug Gwyn) (06/02/91)

In article <4538@inews.intel.com> bhoughto@hopi.intel.com (Blair P. Houghton) writes:
>In article <16317@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>>malloc(0) should return either NULL or a pointer to some storage location.
>>Technically the behavior is undefined, since there are no objects of the
>>specified size (0) according to the standard.
>	"If the size of the space requested is zero, the behavior
>	 is implementation-defined; the value returned shall be
>	 either a null pointer or a unique pointer."
>		 (ANSI X3.159-1989, sec. 4.10.3, p. 155, ll. 18-20)

Oops, thanks for pointing that out.  (I remembered the committee debate
on the issue, but not the outcome.)  Thus the "should" in my response
becomes a "must" and "undefined" should have been "implementation-defined".

I think, but am not sure, that malloc()ed storage is intended to be such
that the address (one past the end) of the requested amount of storage
be meaningful (but its "contents" not necessarily accessible), just as for
explicitly declared arrays.

>I.e., `malloc(0)' must "eat" space if it does not return NULL, ...

The rest of that discussion seemed confusing.  I think it is easier to
simply say that the implementation has the choice (which must be
documented) of EITHER simply returning NULL for a 0-sized request, OR
acting in effect as though the request had been for just 1 byte.  In some
situations the ability to not actually make the additional storage
accessible might be of some use to the implementor; however, since a
strictly conforming program cannot count on 0-sized malloc()s succeeding
even when there is plenty of unallocated storage available, it is hardly
worth making such an optimization for this special case (which hardly any
program will ever tickle).

Generally I would think that reasonable implementations of malloc()
would naturally support successful 0-sized allocations with no special
coding for the 0-sized case.  Certainly this would be true for "block
header" style schemes; for "buddy system" schemes (which I don't
recommend), there would have to be a simple fudge (such as
"if(bytes_wanted==0)++bytes_wanted;" to obtain the required "unique
pointer" property.

flaps@dgp.toronto.edu (Alan J Rosenthal) (06/02/91)

bhoughto@hopi.intel.com (Blair P. Houghton) writes:
>But, the pointer, if it is returned, points to an address which is correctly
>aligned for _any_ object.  Whether this has any use I do not know.

It's presumably useful to be able to assign it to some pointer variable and be
able to test for equality.  If the pointer wasn't necessarily suitably aligned,
then two different ones might compare equal after being converted, say, to
pointers to struct blop.

ajr