From 3e396148edfe91214c7baa03492f523ca53680e8 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Sun, 10 Jul 2016 14:50:59 -0600 Subject: [PATCH] MAINT: Allocate fewer bytes for empty arrays. Currently the number of bytes allocated is the product of the non-zero dimensions x element_size, which can create huge memory allocations for empty arrays. Change that to just allocate enough for one element. Some allocation is needed for the array.data attribute to work correctly. Note: Could probably allocate a minimal number of bytes, say 16 as dictated by alignment, but the old intended number is used here as a more conservative fix. Closes #7813. --- numpy/core/src/multiarray/ctors.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index a03bacceb53b..b2ef0c451c01 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -902,7 +902,7 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, int allow_emptystring) { PyArrayObject_fields *fa; - int i; + int i, is_empty; npy_intp nbytes; if (descr->subarray) { @@ -953,6 +953,7 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, } /* Check dimensions and multiply them to nbytes */ + is_empty = 0; for (i = 0; i < nd; i++) { npy_intp dim = dims[i]; @@ -961,13 +962,13 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, * Compare to PyArray_OverflowMultiplyList that * returns 0 in this case. */ + is_empty = 1; continue; } if (dim < 0) { PyErr_SetString(PyExc_ValueError, - "negative dimensions " \ - "are not allowed"); + "negative dimensions are not allowed"); Py_DECREF(descr); return NULL; } @@ -1041,8 +1042,9 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, * Allocate something even for zero-space arrays * e.g. shape=(0,) -- otherwise buffer exposure * (a.data) doesn't work as it should. + * Could probably just allocate a few bytes here. -- Chuck */ - if (nbytes == 0) { + if (is_empty) { nbytes = descr->elsize; } /*