realloc and malloc and zero-sized objects

Mark Brader msb at sq.com
Mon Apr 10 09:09:19 AEST 1989


[I'm posting this back to comp.lang.c as well as comp.std.c because the
 second part of the article discusses an "existing implementations" topic.]

Well, I should have known better.  Usually when I post articles citing
the proposed Standard (pANS), they deal with a topic that is of importance
to me, and thus one on which I've read the pANS carefully at some time.
I'm not a fan of zero-sized objects, and elected to post anyway, and I
got it wrong.

I wrote:

> > > Does [realloc] return NULL ... when it acts like free ...?
> > It's implementation defined -- the implementation is allowed to
> > return either a NULL pointer or a pointer to a zero-sized object
> Perhaps right as regards existing implementations, but wrong as regards
> the proposed Standard.

This is still correct.  However, I then cited #1.6 to show that zero-sized
objects are prohibited in pANS C, cited #4.10.3.3 to show that malloc(0) is
an attempt to allocate such an object, and used the general rule in #4.1.6
on argument values out of their domain, to conclude that:

> Since 0 is not a possible size for an object, the invocation malloc(0)
> falls under the general rule and is undefined behavior.  It would of
> course be permissible for an implementation to define its behavior in
> this circumstance; this would be an extension to the language.

Bzzt!  Jerry Schwarz of Bell Labs sent email, and Larry Jones posted in
comp.std.c, both pointing out my error.  Before concluding that the general
rule (#4.1.6) applied because #4.10.3.3 didn't have anything to override it,
I should also have looked at the higher-level sections #4.10.3 and #4.10.
Had I done so, I would have found:

#  #4.10.3 Memory management functions
#
#  ... 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.

However, contrary to Larry's article, I claim that this still affects only
malloc(0) and realloc(0,0).  [I use here the terse syntax valid only if
there's a prototype in scope.]  The case of realloc(p,0) where p isn't a
null pointer is covered explicitly.  As I said before, #4.10.3.4 says
this about that:

#	void *realloc (void *ptr, size_t size);
#  ... If size is zero and ptr is not a null pointer, the object it
#  points to is freed.

I claim that this is defining this situation *not* to be a request to
allocate space; in that case the words of #4.10.3 do not apply, and so
realloc() must not return a unique pointer, and so it must return a
null pointer.


By the way, I put a semicolon in place of the comma in the prototype syn-
tax last time.  This was a typo induced by having used Algol in the past.
I personally would have preferred the Algol-like syntax there for
delimiting arguments, even though I prefer C syntax generally.


I also wrote:

> [Discussion of other invalid pointer values, giving undefined behavior,
> omitted.]

Then, yesterday, I bought a copy of Andrew Koenig's "C Traps and Pitfalls",
which looks like worthwhile reading for most people who ask questions in
these newsgroups.  And people who answer questions wouldn't do badly to read
it either, especially if they ever get the answers wrong.  And besides, it
mentions my name, so it must be good!  :-)

The book quotes the V7 UNIX manual as follows:

!  Realloc also works if ptr points to a block freed since the last call
!  of realloc, malloc, or calloc.

He goes on to point out that this behavior is descended from a still
earlier form of realloc() that *required* realloc(p,n) to be preceded
by free(p).

Existing implementations now often do not support this behavior, and the
pANS, in the section I skipped over, explicitly makes such a sequence of
calls undefined behavior.


#  #4.10.3 Memory management functions
#  ... The value of a pointer that refers to freed space is indeterminate.

#  #4.10.3.4 The realloc function
#
#  ... Otherwise [i.e. if ptr isn't a null pointer], if ptr does not match
#  a pointer earlier returned by the calloc, malloc, or realloc function,
#  or if the space has been deallocated by a call to the free or realloc
#  function, the behavior is undefined.


Now, as I said last time (and this time I mean it!)....
This article is cross-posted to comp.lang.c and comp.std.c, as was
the one it's a followup to, but I've directed further followups to
comp.std.c.  Followups discussing *existing* implementations should
go to comp.lang.c instead, though, and followups on the topic of how
to write a null pointer constant should not be posted at all.
(To which I now add, likewise for followups on the topic of what syntax
should have been adopted for delimiters in prototypes!)

-- 
Mark Brader, Toronto		"The singular of 'data' is not 'anecdote.'"
utzoo!sq!msb, msb at sq.com				-- Jeff Goldberg

This article is in the public domain.



More information about the Comp.lang.c mailing list