#821 vectors __getitem__ and ref counting

Marcelo Matus
python (259)
J Robert Ray

I'm on swig-1.3.31.

The way vectors are wrapped, getting an item out of a vector will return an object that is effectively a wrapped pointer, but its validity depends on the lifespan of the vector.

v = vector()
item = v[3]
del v

# segfault
print item.foo

I didn't notice this being documented anywhere.

Note that this is the kind of code I was getting a crash on:

def get():
return vector()

# segfault
print get()[3].foo

Python optimistically decrefs the result of get() after calling __getitem__ but before __getattr__. It took me a while to understand this and realize why it was crashing.

I think the bug in all of this is that __getitem__ does not increase the reference count of the vector instance it is a member of, and python may choose to delete the vector while objects that refer to its memory still exist.

Ideally the object wrapping the result of v[3] would hold a reference to v to prevent this dangling pointer problem.