[Numpy-discussion] Accessing array members

Joachim Saul list at jsaul.de
Mon Dec 2 03:02:17 EST 2002


Hi there,

given the following (simplified) scenario:

typedef struct {
        PyObject_HEAD
        float bar[10];
} FooObject;

I want to be able to set and retrieve the elements of bar from
Python using e.g.

>>> foo = Foo()
>>> foo.bar[4] = 1.23
>>> x = foo.bar[4]

I have chosen an approach using 'PyArray_FromDimsAndData'. In fact
I programmed it after studying 'arrayobject.c', namely the part in
'array_getattr' where the 'flat' attribute is accessed.

foo_getattr(FooObject *self, char *name)
{
        if (!strcmp(name, "bar")) {
                int n=10;
                PyObject *bar = PyArray_FromDimsAndData(1, &n,
                                    PyArray_FLOAT, (char*)self->bar);
                if (bar == NULL) return NULL;
                return bar;
        }

        return Py_FindMethod(foo_methods, (PyObject*)self, name);
}

And it works! :-)

BUT how about refcounts here? 'PyArray_FromDimsAndData' will
return an array which only contains a reference to foo's original
bar array; that's why I can both set and access the latter the way
described. And no memory leak is created.

But what if I create a reference to foo.bar, and later delete foo,
i.e.

>>> b = foo.bar
>>> del foo

Now the data pointer in b refers to freed data! In the mentioned
'array_getattr' this apeears to be solved by increasing the
refcount; in the above example this would mean 'Py_INCREF(self)'
before returning 'bar'. Then if deleting 'foo', its memory is not
freed because the refcount is not zero. But AFAICS in this case
(as well as in the Numeric code) the INCREF prevents the object
from EVER being freed. Who would DECREF the object?

Or am I misunderstanding something here?

In my actual code I can perfectly live with the above solution
because I only need to access foo's data using 'foo.bar[i]' and
probably never need to create a reference to 'bar' which might
survive the actual 'foo' object. However, I want to program it the
'clean' way; any hints on how to do it properly would therefore be
highly welcome.

Cheers,
Joachim




More information about the NumPy-Discussion mailing list