[C++-sig] Re: Dangling Reference Exception dramas

David Abrahams dave at boost-consulting.com
Wed May 21 16:39:06 CEST 2003


"Daniel Paull" <dlp at fractaltechnologies.com> writes:

> Hello,
>
> I've hit a situation somewhat similar to that mentioned in the, "I'm
> getting the "attempt to return dangling reference" error. What am I
> doing wrong?", section of the FAQ.
>
> The FAQ describes a situation like this:
>
>   period const& get_floating_frequency() const
>   {
>     return boost::python::call_method<period const&>(
>       m_self,"get_floating_frequency");
>   }
>
>   class MyClass( ... ):
>     def get_floating_frequency( self ):
>       return period( 25 )
>
> Clearly, the period C++ object will be destroyed as the returned python
> object is garbage collected, as noted in the FAQ.  However, the object
> being returned in my case is an attribute of the class.  For example:
>
> class MyClass( ... ):
>     def __init__( self ):
> 	self.period = period( 25 )
>
>   def get_floating_frequency( self ):
>     return self.period
>
> By my reckoning this should be safe (so long as I manage the lifetime of
> the class instance properly).  However, I still get a ReferenceException
> raised.

What is the precise code which causes the exception?  Can you post a
reduced test case?

> Looking at the boost.python code I see (in from_python.cpp):
>
> ----------------------------------------------------------------------
> void* lvalue_result_from_python(
>       PyObject* source
>       , registration const& converters
>       , char const* ref_type)
>   {
>       handle<> holder(source);
>       if (source->ob_refcnt <= 2)
>       {
>           handle<> msg(
>               ::PyString_FromFormat(
>                   "Attempt to return dangling %s to object of type: %s"
>                   , ref_type
>                   , converters.target_type.name()));
>           
>           PyErr_SetObject(PyExc_ReferenceError, msg.get());
>
>           throw_error_already_set();
>       }
>       
>       void* result = get_lvalue_from_python(source, converters);
>       if (!result)
>           (throw_no_lvalue_from_python)(source, converters, ref_type);
>       return result;
>   }  
> }
> ----------------------------------------------------------------------
>
> I'm wondering if the "<= 2" test should be "< 2".  Where does the second
> ref come from?

Well, "<=2" was right once upon a time, but I see that I have no
tests for this case in the test suite.  I could try to track this
down, but it would be a lot faster if you'd post the test which
causes the problem.

> Anyway, the FAQ doesn't offer me a solution to the problem - is there a
> preferred method for doing what I want to do?

I can't tell what you want to do until you show me the code ;-)

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list