python列表的实现错误调整大小?

时间:2015-07-31 23:41:31

标签: c python-3.x

在list(Python 3.4)的实现中,我看到了以下内容:

static int
list_resize(PyListObject *self, Py_ssize_t newsize)
{
    PyObject **items;
    size_t new_allocated;
    Py_ssize_t allocated = self->allocated;

    /* Bypass realloc() when a previous overallocation is large enough
       to accommodate the newsize.  If the newsize falls lower than half
       the allocated size, then proceed with the realloc() to shrink the list.
    */
    if (allocated >= newsize && newsize >= (allocated >> 1)) {
        assert(self->ob_item != NULL || newsize == 0);
        Py_SIZE(self) = newsize;
        return 0;
    }

    new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);

    /* check for integer overflow */
    if (new_allocated > PY_SIZE_MAX - newsize) {
        PyErr_NoMemory();
        return -1;
    } else {
        new_allocated += newsize;
    }

    if (newsize == 0)
        new_allocated = 0;
    items = self->ob_item;
    if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *)))
        PyMem_RESIZE(items, PyObject *, new_allocated);
    else
        items = NULL;
    if (items == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    self->ob_item = items;
    Py_SIZE(self) = newsize;
    self->allocated = new_allocated;
    return 0;
}

具体地说:

PyMem_RESIZE(items, PyObject *, new_allocated);

我怎么知道,realloc可能返回另一个指针,与获得的指针不同。我不明白它是如何稳定运作的。

1 个答案:

答案 0 :(得分:4)

这是PyMem_Resize的定义:

#define PyMem_Resize(p, type, n) \
    ( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )

因此它会就地修改指针items

另见https://docs.python.org/3/c-api/memory.html#c.PyMem_Resize