[C++-sig] Calling list.__len__() from C++ causes crash with >= 100 elements

Alex Mohr amohr at pixar.com
Mon Aug 7 18:46:18 CEST 2006


>> void printListLength(boost::python::object elements)
>> {
>>     boost::python::extract<int> lenExtract( elements.attr( "__len__" )() );
>>     if ( lenExtract.check() )
>>     {
>>         int numElements = lenExtract;
>>         std::cout << numElements << " elements" << std::endl;
>>     }
>> }
> 
> I can reproduce your problem under FC3 and FC5 (both x86_64). I am not sure if
> this is a bug or a feature. In any case, this workaround does the trick for me:

It is apparently a feature.  We've had a similar bug before as well.

You're creating a c++ temporary holding a new python object when you do 
"elements.attr("__len__")()" and passing it off to the extractor, and 
then you attempt to invoke the extractor later after the c++ temporary 
has died.

The problem is that the extractor does not keep a reference to the 
python object it was constructed with (and is documented accordingly). 
So, by the time you invoke the extractor, the python object it's got is 
long since dead, and you get a crash.

The fix posted in the parent message is the correct one.  You need to 
make sure the object you pass to the extractor lives at least as long as 
the last invocation of the extractor.

Here's the documentation:

http://www.boost.org/libs/python/doc/v2/extract.html#extract-spec

Note this sentence:
"Stores a pointer to the Python object managed by its constructor 
argument. In particular, the reference count of the object is not 
incremented. The onus is on the user to be sure it is not destroyed 
before the extractor's conversion function is called."

When we came across this, we wondered why it would be bad for the 
extractor to take a reference to its argument.  David -- can you shed 
some light on this?

Alex



More information about the Cplusplus-sig mailing list