Reference Count Confusion
Jeff Smith
smithj at kryos.colorado.edu
Tue Jun 25 16:41:01 EDT 2002
I'm a little puzzled about reference counts from Python objects created
in a C extension. In the following example, I return a Numerical Python
array from a C function (function 'add' ). Just before the return,
I printed the reference count, and is was 1, as expected. When I passed
the returned array into another C function (function 'clean'), it's
reference count was 3. This wasn't what I expected, and probably
explains why when I incorporate C functions into my Python programs
I chew up gobs of memory. I'm presumably doing something wrong. Am
I supposed to decrement the reference count somewhere?
Python code:
import Numeric
import foo
a = Numeric.zeros(1000000).astype('f')
b = Numeric.ones(1000000).astype('f')
for i in range(10):
d = foo.add(a, b)
foo.clean(d)
C code (module 'foo'):
static PyObject *add(PyObject *self, PyObject *args)
{
PyArrayObject *a, *b, *c;
float *cb, *cc, *ca;
int i;
long buffer_size;
if (!PyArg_ParseTuple(args, "OO", &a, &b))
{
return NULL;
}
buffer_size = a->dimensions[0];
ca = (float *)a->data;
cb = (float *)b->data;
cc = (float *)malloc(buffer_size*sizeof(float));
for (i = 0; i < buffer_size; i++)
{
cc[i] = ca[i] + cb[i];
}
c = (PyArrayObject *)PyArray_FromDims(1, (int *)&buffer_size, PyArray_FLOAT);
memcpy(c->data, cc, buffer_size*sizeof(float));
free(cc);
printf("add: %d\n", c->ob_refcnt);
return Py_BuildValue("O", c);
}
static PyObject *clean(PyObject *self, PyObject *args)
{
PyArrayObject *c;
PyArg_ParseTuple(args, "O", &c);
printf("clean: %d\n", c->ob_refcnt);
if (c->data != NULL) free(c->data);
if (c->dimensions != NULL) free(c->dimensions);
if (c->strides == NULL) free(c->strides);
Py_DECREF(c);
printf("clean: %d\n", c->ob_refcnt);
return Py_BuildValue("");
}
--
More information about the Python-list
mailing list