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