[Python-Dev] PyMem_Realloc corner case

Jason Orendorff jason@jorendorff.com
2002年3月14日 11:54:57 -0600


Tim Peters wrote:
> [Jason Orendorff]
> > I just got bit by the following:
> >
> > On Windows,
>> Which flavor of Windows? Which compiler? Which version of Python?

Ah! I just got this message. You correctly divined the cause of
my problems without all this information, so I'll cut to the chase:
> [...] realloc'ing to 0 bytes is stupid [...]

Enough said.
I will indulge in a little whining though (below).
> MS malloc(0) does not return NULL, which is why MALLOC_ZERO_RETURNS_NULL
> should not be #define'd. However, MS realloc(p, 0) returns NULL 
> if and only if p is not NULL (well, MS realloc(NULL, 0) can return
> NULL if there's not enough heap space remaining to allocate a dummy
> object), and if p is not NULL does free the block. All of this is
> fine by the C standard.
> [...]
> Note: The pymalloc realloc works just like the MS realloc here, 
> so it's not "just Windows"; from obmalloc.c's _THIS_REALLOC:
>> 			/* Don't bother if a smaller size was requested
> 			 except for realloc(p, 0) == free(p), ret NULL */
> 			if (nbytes == 0) {
> 				_THIS_FREE(p);
> 				bp = NULL;
>> In fact, I believe it's *common* for realloc(not-NULL, 0) to act like
> free(not-NULL), and that's allowed but not required by C.

Well... here's what the standard says:
| 7.20.3 Memory management functions
| 1 [...]
| If the size of the space requested is zero, the behavior is
| implementation-defined: either a null pointer is returned, or the
| behavior is as if the size were some nonzero value, except that the
| pointer returned shall not be used to access an object.

This applies to calloc, malloc, and realloc. And:
| 7.20.3.4 The realloc function
| Synopsis
| #include <stdlib.h>
| void *realloc(void *ptr, size_t size);
| Description
| 2 The realloc function deallocates the old object pointed to
| by ptr and returns a pointer to a new object that has the size
| specified by size. The contents of the new object shall be the
| same as that of the old object prior to deallocation, up to the
| lesser of the new and old sizes.

If you set knowing how Microsoft's realloc() or PyMalloc's
realloc() works, you could read the standard to allow them.
But a casual reading suggests
(a) "the behavior is implementation-defined: either X or Y"
 - a given implementation must pick one or the other, not
 switch back and forth for different cases.
(b) "deallocates the old object...returns a pointer to a new
 object" - should behave like a free/malloc combo. That is,
 y=realloc(x, 0); should behave like free(x); y=malloc(0);
Anyway, I'm sure you've had enough of me by now, so I'll stop. :)
## Jason Orendorff http://www.jorendorff.com/

AltStyle によって変換されたページ (->オリジナル) /