summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-03-02 08:43:19 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-03-02 08:43:19 (GMT)
commita5d78cc208c24be62b50b6d1540e03be6612d3f2 (patch)
treeeda122d61fdabb1c1579ab4d8ff0898872a15f7c
parentb77d343bc846c2049a4cffb1dfd65eb49d1728b4 (diff)
downloadcpython-a5d78cc208c24be62b50b6d1540e03be6612d3f2.zip
cpython-a5d78cc208c24be62b50b6d1540e03be6612d3f2.tar.gz
cpython-a5d78cc208c24be62b50b6d1540e03be6612d3f2.tar.bz2
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.
-rw-r--r--Include/pymem.h19
-rw-r--r--Include/pyport.h12
-rw-r--r--Objects/object.c7
3 files changed, 24 insertions, 14 deletions
diff --git a/Include/pymem.h b/Include/pymem.h
index 86a69e4..d09f38c 100644
--- a/Include/pymem.h
+++ b/Include/pymem.h
@@ -111,13 +111,18 @@ extern DL_IMPORT(void) PyMem_Free(void *);
/* Macros */
#define PyMem_NEW(type, n) \
( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) )
-#define PyMem_RESIZE(p, type, n) \
- if ((p) == NULL) \
- (p) = (type *)(PyMem_MALLOC( \
- _PyMem_EXTRA + (n) * sizeof(type))); \
- else \
- (p) = (type *)(PyMem_REALLOC((p), \
- _PyMem_EXTRA + (n) * sizeof(type)))
+
+/* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
+#define PyMem_RESIZE(p, type, n) \
+ do { \
+ size_t _sum = (n) * sizeof(type); \
+ if (!_sum) \
+ _sum = 1; \
+ (p) = (type *)((p) ? \
+ PyMem_REALLOC(p, _sum) : \
+ PyMem_MALLOC(_sum)); \
+ } while (0)
+
#define PyMem_DEL(p) PyMem_FREE(p)
/* PyMem_XDEL is deprecated. To avoid the call when p is NULL,
diff --git a/Include/pyport.h b/Include/pyport.h
index 271ec43..a831b26 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -366,8 +366,16 @@ extern double hypot(double, double);
#endif
#ifdef MALLOC_ZERO_RETURNS_NULL
-/* XXX Always allocate one extra byte, since some malloc's return NULL
- XXX for malloc(0) or realloc(p, 0). */
+/* Allocate an extra byte if the platform malloc(0) returns NULL.
+ 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
#else
#define _PyMem_EXTRA 0
diff --git a/Objects/object.c b/Objects/object.c
index 8babf79..bcc129c 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1894,11 +1894,8 @@ PyMem_Malloc(size_t nbytes)
void *
PyMem_Realloc(void *p, size_t nbytes)
{
-#if _PyMem_EXTRA > 0
- if (nbytes == 0)
- nbytes = _PyMem_EXTRA;
-#endif
- return PyMem_REALLOC(p, nbytes);
+ /* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
+ return PyMem_REALLOC(p, nbytes ? nbytes : 1);
}
void