mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Whether platform malloc(0) returns NULL has nothing to do with whether
platform realloc(p, 0) returns NULL, so MALLOC_ZERO_RETURNS_NULL can be correctly undefined yet realloc(p, 0) can return NULL anyway. Prevent realloc(p, 0) doing free(p) and returning NULL via a different hack. Would probably be better to get rid of MALLOC_ZERO_RETURNS_NULL entirely. Bugfix candidate.
This commit is contained in:
parent
b77d343bc8
commit
a5d78cc208
3 changed files with 24 additions and 14 deletions
|
@ -111,13 +111,18 @@ extern DL_IMPORT(void) PyMem_Free(void *);
|
||||||
/* Macros */
|
/* Macros */
|
||||||
#define PyMem_NEW(type, n) \
|
#define PyMem_NEW(type, n) \
|
||||||
( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) )
|
( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) )
|
||||||
#define PyMem_RESIZE(p, type, n) \
|
|
||||||
if ((p) == NULL) \
|
/* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
|
||||||
(p) = (type *)(PyMem_MALLOC( \
|
#define PyMem_RESIZE(p, type, n) \
|
||||||
_PyMem_EXTRA + (n) * sizeof(type))); \
|
do { \
|
||||||
else \
|
size_t _sum = (n) * sizeof(type); \
|
||||||
(p) = (type *)(PyMem_REALLOC((p), \
|
if (!_sum) \
|
||||||
_PyMem_EXTRA + (n) * sizeof(type)))
|
_sum = 1; \
|
||||||
|
(p) = (type *)((p) ? \
|
||||||
|
PyMem_REALLOC(p, _sum) : \
|
||||||
|
PyMem_MALLOC(_sum)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define PyMem_DEL(p) PyMem_FREE(p)
|
#define PyMem_DEL(p) PyMem_FREE(p)
|
||||||
|
|
||||||
/* PyMem_XDEL is deprecated. To avoid the call when p is NULL,
|
/* PyMem_XDEL is deprecated. To avoid the call when p is NULL,
|
||||||
|
|
|
@ -366,8 +366,16 @@ extern double hypot(double, double);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MALLOC_ZERO_RETURNS_NULL
|
#ifdef MALLOC_ZERO_RETURNS_NULL
|
||||||
/* XXX Always allocate one extra byte, since some malloc's return NULL
|
/* Allocate an extra byte if the platform malloc(0) returns NULL.
|
||||||
XXX for malloc(0) or realloc(p, 0). */
|
Caution: this bears no relation to whether realloc(p, 0) returns NULL
|
||||||
|
when p != NULL. Even on platforms where malloc(0) does not return NULL,
|
||||||
|
realloc(p, 0) may act like free(p) and return NULL. Examples include
|
||||||
|
Windows, and Python's own obmalloc.c (as of 2-Mar-2002). For whatever
|
||||||
|
reason, our docs promise that PyMem_Realloc(p, 0) won't act like
|
||||||
|
free(p) or return NULL, so realloc() calls may have to be hacked
|
||||||
|
too, but MALLOC_ZERO_RETURNS_NULL's state is irrelevant to realloc (it
|
||||||
|
needs a different hack).
|
||||||
|
*/
|
||||||
#define _PyMem_EXTRA 1
|
#define _PyMem_EXTRA 1
|
||||||
#else
|
#else
|
||||||
#define _PyMem_EXTRA 0
|
#define _PyMem_EXTRA 0
|
||||||
|
|
|
@ -1894,11 +1894,8 @@ PyMem_Malloc(size_t nbytes)
|
||||||
void *
|
void *
|
||||||
PyMem_Realloc(void *p, size_t nbytes)
|
PyMem_Realloc(void *p, size_t nbytes)
|
||||||
{
|
{
|
||||||
#if _PyMem_EXTRA > 0
|
/* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
|
||||||
if (nbytes == 0)
|
return PyMem_REALLOC(p, nbytes ? nbytes : 1);
|
||||||
nbytes = _PyMem_EXTRA;
|
|
||||||
#endif
|
|
||||||
return PyMem_REALLOC(p, nbytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue