[issue13091] ctypes: memory leak

Meador Inge report at bugs.python.org
Mon Oct 3 02:22:15 CEST 2011


Meador Inge <meadori at gmail.com> added the comment:

> this pointer is tied to a CDataObject; its tp_alloc should free the 
> memory

The free in 'PyCData_clear' is conditional:

    if ((self->b_needsfree)
        && ((size_t)dict->size > sizeof(self->b_value)))
        PyMem_Free(self->b_ptr);

As written, 'PyCData_clear' has no way of knowing that memory has been 
{m,re}alloc'd in 'resize'.  So in some cases memory will leak.  Here is 
a small reproduction case extracted from 'test_varsize_struct.py'.

    from ctypes import *

    class X(Structure):
        _fields_ = [("item", c_int),
                    ("array", c_int * 1)]

    x = X()
    x.item = 42
    x.array[0] = 100
    new_size = sizeof(X) + sizeof(c_int) * 5
    resize(x, new_size)

One potential fix is:

diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -2440,7 +2440,7 @@ PyCData_clear(CDataObject *self)
     assert(dict); /* Cannot be NULL for CDataObject instances */
     Py_CLEAR(self->b_objects);
     if ((self->b_needsfree)
-        && ((size_t)dict->size > sizeof(self->b_value)))
+        && (self->b_ptr != (char *)&self->b_value))
         PyMem_Free(self->b_ptr);
     self->b_ptr = NULL;
     Py_CLEAR(self->b_base);

I need to think about that more, though.

----------
versions: +Python 2.7, Python 3.2

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue13091>
_______________________________________


More information about the Python-bugs-list mailing list