Trying to malloc() 0 bytes on AIX fails, but works on Ultrix, IRIX,
Dynix, SunOS, BSD, MIPS RiscOS.
OK, it's documented in the man page on AIX, but it's a pointless and
annoying inconsistency. I wish AIX was UNIX.
#include <stdio.h>
#include <malloc.h>
main()
{
if ( malloc( (unsigned)0 ) == NULL )
printf("malloc(0) failed\n"); /* only on AIX */
else
printf("malloc(0) worked\n"); /* works on UNIX */
exit(0);
}
John Sellens
University of Waterloo
jmse...@watdragon.uwaterloo.ca
It's explicitly forbidden by SVID, as I recall. AIX is SVID
compliant. Are any of the other systems you mentioned? (Apparently
not.) Trying to make folks happy who think "UNIX == BSD" and those who
think, "UNIX == System V" ain't always possible.
"The nice thing about standards is there are so many of them."
Pardon? What do you mean `it works'? Sure it returns a non-null pointer but
what are you going to do with that? You asked for no space to be allocated so
how are you going to use that pointer-to-nothing??? For your information,
AIX is not the only system which will give you a null pointer -- so will
Solaris 2 (SVR4) if you link with -lmalloc.
|> OK, it's documented in the man page on AIX, but it's a pointless and
|> annoying inconsistency. I wish AIX was UNIX.
Actually, documenting it is EXACTLY what AIX should do according to the ANSI
(ISO) C standard. ISO/IEC 9899:1990 (E) Section 7.10.3 says:
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.
So don't rely on malloc(0) doing anything portable!
There are times when I'm glad that AIX is not UNIX-as-we-know-and-love-it! I'm
concerned with writing portable code and it's sometimes really useful to have a
platform which interprets standards in a different, but legal, manner.
|> John Sellens
|> University of Waterloo
|> jmse...@watdragon.uwaterloo.ca
* Neil Winton BT Labs, Rm 306 SSTF, Martlesham Heath *
* N.Wi...@axion.bt.co.uk IPSWICH IP5 7RE, UK (Tel +44 473 646079) *
* The works of the Lord are great, sought out of all them that have *
* pleasure therein. Psalm 111 v 2 *
* (Found at the entrance to the Cavendish Labs, Cambridge.) *
Having researched this recently, the comment about SVID compliance is
not 100% correct. AIX (at 3.2) is now POSIX compliant for system calls.
Or, alternatively, AIX is compliant with SVID except where it conflicts
with POSIX or XPG.
The following is copied from a letter I received from David Luner
(Lu...@vnet.ibm.com) Thanks David.
"AIX/6000 Version 3.2 is based upon UNIX System V and conforms to the IEEE
POSIX Standard 1003.1 - 1990, is compatible with 4.3 BSD and is designed to
meet Trusted Computing Base level C2 security." (from the sales manual)
"AIX/6000 Version 3.2 which is IBM's implementation of UNIX System V
Release 3 (SVID) running on the RISC System/6000 has been tested using
the USL (UNIX System Laboratory) System V Verification Suite and conforms
to the Base System as specified in Issue 2 of the USL System V Interface
Definition Volumes 1, 2 and 3. AIX/6000 Version 3.2 complies with SVID-2
except where it conflicts with International Standards, National
Standards, National Institute of Standards and Testing (NIST), or X/Open."
This has led to confusion in the past with BSDites and the SysVites
saying that AIX is so screwed up because it doesn't do either right.
Such is life in the world of 'Open Systems' and 'Standards'.
Brandon
--
H. Brandon Guest | bgu...@ems.cdc.com
Empros Systems International | (A division of Something)
2300 Berkshire Lane North | Voice (612) 553-4529
Plymouth, MN 55441-3694 | Fax (612) 553-4018
If you call:
mallopt(1,0);
Somewhere in your program, malloc(0) will no longer return NULL.
-Jim Zelenka
jz...@andrew.cmu.edu
> Pardon? What do you mean `it works'? Sure it returns a non-null pointer but
> what are you going to do with that? You asked for no space to be allocated so
> how are you going to use that pointer-to-nothing?
The most standard use I know of for malloc(0) is to get a pointer that
can be passed to realloc(). In any case, this behavior of the AIX malloc
package is documented, and can be changed with mallopt, which is just
about all you can ask for in an operation whose results are defined as
implementation-specific.
-Jim Zelenka
jz...@andrew.cmu.edu
That's a neat trick. Info Explorer is misleading about mallopt():
"Nothing done with the mallopt subroutine affects how memory is
allocated by the system."
--
David Joyner (nsy...@acs.ncsu.edu)
Unix Systems Programmer | Phone: (919) 515-2794 |
NCSU Administrative Computing Services | FAX: (919) 515-3787 |
Thanks for posting a documented feature. Now please go through all the AIX
manuals and post all such potential problems that are bound to cause problems
like this (I allocate zero bytes every day for my imaginary structures in my
imaginary programs), and make any effort to make these posting as lengthy as
possible to flood the world with more crud that we could ever handle.
Thanks also for posting the progy -- we could never write our own to
allocate 0 bytes and check for the return address from malloc(); sharing code
is important I think.
Tasos
Well, you could free() it. Or realloc() it to a larger size later.
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.
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.
To be fair, AIX isn't unique in this regard -- most SysV based systems
work this way. Like most of the features unique to SysV, this one is
a botch.
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?
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?
>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.
They've always been undefined! Why depend on some implementation-specific
behavior when C gives you the opportunity to do otherwise?
>To be fair, AIX isn't unique in this regard -- most SysV based systems
>work this way. Like most of the features unique to SysV, this one is
>a botch.
To most BSD users, SysV is a botch! (I used BSD in college and was a
BSD bigot until I was forced to use SysV... And forced to realize
what it took to write BSD/SysV portably programs)
Craig
--
Craig Miller, software mechanic: AIXV3 Change Team (Level3 support)
#include <ibm/stds/disclaimer.h>
char *internet = "d...@austin.ibm.com", *vnet = "AUSVM6(TKG007)";
You may want to pick up the latest snapshot of the zephyr sources from
athena-dist.mit.edu; this bug has since been fixed in a more portable way.
Given that the documentation (at least in the 3.2 InfoExplorer) says
"Nothing done with the mallopt subroutine affects how memory is allocated by
the system", relying on it to cause malloc(0) to allocate memory where it
wouldn't previously is not likely to be a good long-term solution.
-Lucien
--
-----------------------------------------------------------------------
Lucien Van Elsen IBM Research
luc...@watson.ibm.com Project Agora
Nope. Most code that expects malloc(0) to return a pointer to
0 bytes does something like
if (!(ptr=malloc(foo))) goto NO_MEMORY;
My example still works. Always. However, I think I understand
what you're saying. It should be something like:
if (length == 0)
ptr = NULL;
else if ((ptr = malloc(length)) == NULL)
goto NO_MEMORY;
Still, code that depends on any particular behavior of malloc(0)
is unportable. Period.
And work would be easy if we all ran the same stuff that worked the same
way, did the same things, and gave us the same capabilities. It's not the
'american' way (;-) where "different is better," but it would close down
this thread.
But, think of the threads that would open complaining that "it doesn't error
when I malloc(0) ... shouldn't it return an error?" and so on until it
finally got changed, then you'd have the prior version doing this and that
and a new one that did those and such and on and on and on ...
Rather than complain netwise about the manner in which one set of programs
behaves, why not prove your capabilities and find a most efficient methodology
to stay truly portable without doing handstands? In many cases, if it
weren't for these differences, we
- wouldn't be paid as much as we are;
- wouldn't be working where we are; and,
- wouldn't have jobs because anyone can do it 'cause it's the same!
AIX does all sorts of things BETTER than anything I've seen to date, as well
as all sorts of things WORSE than anything I've seen to date. Likewise for
System V and BSD and for that matter MS-DOS. I _still_ like CP/M! That's a
lot of power packed into 8 Kilobytes of memory ... what an operating system!
C'est la vie.
--
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Bruce T. Harvey {B-}) ::: UUCP: ... {uunet|mimsy}!wb3ffv!idsssd!bruce
MGR-Systems Integration::: INTERNET: wb3ffv!idsssd!bruce%uunet.uu.net@...
INSIGHT Dist. Sys. - SI:::CompuServe: 71033,1070
(410)329-1100 x312,x352::: SnailMail: 222 Schilling Cir.,Hunt Valley, MD 21031
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
I have been told that according to ANSI (I havn't read it myslef), that
no matter what malloc(0) returns, you should be able to free() and
realloc() it. In otherwords, even if malloc(0) returns NULL, it's OK.
It does cause unexpected behaviour if you're not expecting it though.
I've spent many hours tracking down "Out of memory" errors that were
caused by myself or somebody else trying to malloc 0 bytes then
returning an out of memory error just because malloc returned NULL.
--
-Dave Williss
---------------------------------------------------------------------------
Standards are great! Everybody should have one of their own!
The opinions stated above are Mine! All Mine! You can't have them.
I don't think this would happen. malloc(0) for years has returned a unique
pointer on SunOS, Ultrix, HP-UX, ... and I have yet to see anyone complain.
On the other hand I have seen a never ending stream of complaints
about systems where malloc(0) fails.
The only argument I have *ever* heard for malloc(0) failing is that
it is "required by the SVID". (Could someone please quote chapter
and verse where it is required, and not merely permitted?)
Does 100% SVID compliance make AIX dead right?
Of course portable programs must defend against malloc() nonsense.
(The correct coding is non-obvious, as previous articles have revealed.)
But this is a poor justification for continuing the AIX malloc behavior!
This thread reminds me of the ancient debate about left-shifting by 0.
In some C implementations (i << n) was undefined when n == 0
since the hardware did not efficiently support it.
There were people who didn't want to see left shift slowed down just
to handle a dubious and rare special case.
After all, this could be handled portably with:
(n == 0)? i: (i << n)
Tom Truscott
> 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: mo...@cs.utk.edu BITNET: moore@utkvx
Let's stamp out FORTRAN in our lifetime.
It does *not* fail; it returns NULL. Your only problem is that you do
not recognize the difference.
Since the behavior of malloc(0) is undefined according to ANSI, and you
can't expect to read or write data at the returned address anyway, this
is perfectly ligitimate behavior.
GNU malloc() does the same thing, BTW.
--
\ / Charles Hannum, myc...@ai.mit.edu
/\ \ PGP public key available on request. MIME, AMS, NextMail accepted.
Scheme White heterosexual atheist male (WHAM) pride!
Well you can under POSIX (and by extension, AIX), so your argument is
no longer relevant to this group.
Well, uhh, not really. On most?...many?... other platforms
malloc() only returns NULL if it couldn't allocate the requested block.
The fact that AIX malloc doesn't is technically legal but a pain... Lots
of code checks for out of memory conditions with if (!malloc(foo))
>GNU malloc() does the same thing, BTW.
Nope. At least, the version I have doesn't...
Two cents coming up!
While you can argue the pros and cons of code that wants to allocate
zero bytes, having malloc(0) return a pointer means you don't have to
test for special cases or interpret the return from malloc() based on
it's argument. Less code means the program is easier to understand and
less likely to have bugs. Granted the code required is not complex,
but it does not "need" to exist. We didn't need push button radios in
our cars but they made life just a little easier.
Isn't it presumptious to say that objects of size zero don't exist...
Can't exist? They exist logically and mathmatically though this may
trouble some of the more literally minded folk. (I am not directing
this at anyone personally).
I, however, based on experience, would never write code depending on
malloc(0) working (returning a pointer to somewhere). It's the kind of
thing you know will come back to haunt you some day. Whatever my
philosophical beliefs, I still have to use this stuff.
--
===============================================================================
| Email: uunet!shady!kevin kevin%sh...@uunet.uu.net
Kevin Smith | : uunet!shady!DSM530!sts sts%DSM530%sh...@uunet.uu.net
| Voice: DSM Chemicals, Inc 706-849-6839
| : ShadeTree Software, Inc. 908-874-6670
-------------------------------------------------------------------------------
I do not speak for DSM. I do speak for ShadeTree Software!
===============================================================================
malloc(0) also sets errno to EINVAL, so "fails" is a reasonable description.
And recognizing the difference is just the beginning.
There are the problems of getting realloc() to work sensibly,
guaranteeing that malloc()ed pointers are unique, and so on.
Some people finesse the problem as follows:
/* work-around for brain-damaged malloc */
portablemalloc(size_t size)
{
return(malloc(size == 0? 1: size));
}
>Since the behavior of malloc(0) is undefined ..., this
[ malloc(0) returning NULL ]
>is perfectly ligitimate behavior.
But people don't want that particular behavior!
[For AIX folks: Isn't it easier to change malloc() to do what people want
than to keep explaining why it doesn't?]
>GNU malloc() does the same thing, BTW.
(?) If this is brought to the attention of the market-driven GNU folks,
they will fix it pronto.
Tom Truscott
When telnetting in to an RS6000/530 (AIX 3.2), the machine will periodically
'hang' on the connection. If I'm in 'vi' at the time, I can hit ctl-c, vi will
beep at me, and all is well again. If I'm not in vi, the best I seem to be able
to do is close the connection and re-connect.
When I close the connection, the process that I _was_ running doesn't seem
to get notified that I went away, and I have to kill it.
The worst part is that the problem seems to be occuring more frequently now
than ever (~1 per hr) and it's starting to drive me mad.
Thanks for any help / solutions.
Peter
I remember reading about malloc, and specifically the malloc(0) case,
that the result was implementation-specific. Why would you want
to malloc 0 bytes anyway? You can't USE it. It would almost seem
that if your program is mallocing 0 bytes, there might be a bug,
but it all really depends on what you are trying to accomplish.
|"The nice thing about standards is there are so many of them."
Also heard, ".... is that there are so many to choose from."
Heard the other day: "AIX is so close to UNIX it's frustrating."
(Kurt, if you're reading, hello!)
-Brent
--
+-------------------------+
| Brent Burton N5VMG |
| bpb...@tamsun.tamu.edu |
+-------------------------+
rash generalization #1! :-)
>[For AIX folks: Isn't it easier to change malloc() to do what people want
>than to keep explaining why it doesn't?]
uh, wait a minute Tom... hasn't AIX's malloc() returned NULL since
"day 1" (what's that, about 2 3/4 years ago?). If there's even *one*
customer out there that's aware of this behavior and is somehow
depending on this behavior in their application (since AIX has
done it since "day 1"), I don't believe IBM can afford to break
this customer.
The worse thing we can do is break existing applications.
Q: "What kind of idiotic customer would ever do that?"
A0: "Obviously you've never been out in the real world.
Customers do everything."
A1: "Customers are not idiotic. Customers keep us in business."
A2: "Regardless of whether the customer is idiotic or not,
we don't dare break existing applications unless we
absolutely have to."
>>GNU malloc() does the same thing, BTW.
>
>(?) If this is brought to the attention of the market-driven GNU folks,
>they will fix it pronto.
Maybe. Maybe not, if they're also worried about breaking existing
software that was possibly written around that behavior.
>Tom Truscott