Message144797
> 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. |
|
Date |
User |
Action |
Args |
2011-10-03 00:22:15 | meador.inge | set | recipients:
+ meador.inge, amaury.forgeotdarc, belopolsky, skrah |
2011-10-03 00:22:15 | meador.inge | set | messageid: <1317601335.6.0.176142368064.issue13091@psf.upfronthosting.co.za> |
2011-10-03 00:22:15 | meador.inge | link | issue13091 messages |
2011-10-03 00:22:14 | meador.inge | create | |
|