Xref: utzoo comp.std.c:1025 comp.lang.c:17547 Checksum: 58767 Lines: 111 Path: utzoo!sq!msb From: msb@sq.com (Mark Brader) Date: Sun, 9-Apr-89 19:09:19 EDT Message-ID: <1989Apr9.190919.25811@sq.com> Newsgroups: comp.std.c,comp.lang.c Subject: Re: realloc and malloc and zero-sized objects References: <10170@bloom-beacon.MIT.EDU> <686@sdrc.UUCP> <1989Apr5.000608.16582@sq.com> <694@sdrc.UUCP> Reply-To: msb@sq.com (Mark Brader) Followup-To: comp.std.c Organization: SoftQuad Inc., Toronto [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@sq.com -- Jeff Goldberg This article is in the public domain.