From: moore@cs.utk.edu (Keith Moore)
Newsgroups: comp.unix.aix
Subject: Re: malloc(0) fails on AIX and nowhere else I could find ...
Date: 12 Jan 1993 00:33:40 GMT
Organization: Univ. of Tenn. Computer Science, Knoxville
Distribution: world
Reply-To: moore@cs.utk.edu
NNTP-Posting-Host: wilma.cs.utk.edu

In article <C0JvG9.1HBs@austin.ibm.com>, dcm@codesmith.austin.ibm.com (Craig Miller - dcm@austin.ibm.com) writes:
> In article <1ikdebINN6qv@CS.UTK.EDU> moore@cs.utk.edu writes:
> >...
> >Say you're implementing a strings package and your string descriptor
> >looks like struct string { int count; char *ptr }; Now when you assign
> >to a string you want to malloc (or realloc) the right # of bytes and
> >assign the return value from malloc to the ptr.  But with AIX (and
> >many other SysV-based systems), you have to explicitly test in case
> >the string you want to assign is zero length.


> those who support malloc(0):	ptr = malloc(length);
> those who don't:		ptr = (length == 0) ? NULL : malloc(length);
> 
> Right?  And the second case *always* works, regardless of whether the
> local implementation of malloc supports malloc(0) or not.  Right?
>
> So the second case is portable.  Right?

No.  I cannot portably call realloc() or free() with the NULL pointer
returned by malloc(0) on SysV systems.  [If I could do that, I
wouldn't ever need a malloc() function; I'd always call
realloc(NULL,size), which would simplify a lot of code that does
resizing of dynamic structures.  POSIX defines realloc to work this
way, but not all UNIXen do.]

To make your approach portable, I'd have to do this when reallocing :

newptr = ptr ? realloc (ptr, newsize) : malloc (newsize);

Instead, I do this:

#define xmalloc(x) malloc((x) == 0 ? 1 : (x))

which gives me a return value that I can portably pass to free() and
realloc().

> Five or six years ago, when I was developing applications, I wrote all
> my apps the second way.  I realized that malloc(0) had basically been
> undefined since day one.  Wouldn't it be more portable and easier to
> simply design your application this way instead of complaining each time
> you try to port your application to a new box?

Of course I write my code to check for malloc(0).  My point is, if
SysV weren't broken, I wouldn't have to.  

I keep complaining about it because the example is instructive to
others.  Of course, the example is lost on some people -- perhaps the
same people who think that malloc() shouldn't actually have to
allocate backing storage....

malloc(0) *was* originally defined (at least in V7) by someone who had
enough of a clue to realize that it should return something that could
be free'd and realloc'ed.

How many bugs in application has this unfortunate definition of
malloc() caused?  How many extra lines of code have had to be written
to get around the design flaw?  What is the cost in development and
maintenance of all of this extra code?

> >Saying you shouldn't be able to malloc() zero bytes is like saying you
> >shouldn't be able to have a zero-length file, or an empty record in a
> >file, or you shouldn't be able to multiply something by zero.
> 
> I disagree.  Saying you shouldn't be able to malloc() zero bytes is
> similiar to saying you can't strcpy() NULL: the behavior is undefined.

No.  It's like saying you shouldn't be able to strcat(foo, "").

When you say that malloc(0) is undefined -- that's the bug!  It's not
meaningless to ask for a pointer to a block containing zero bytes of
storage.  In fact, it's quite useful.

--
Keith Moore / U.Tenn CS Dept / 107 Ayres Hall / Knoxville TN  37996-1301
Internet: moore@cs.utk.edu      BITNET: moore@utkvx
Let's stamp out FORTRAN in our lifetime.