[C++-sig] Dangling Reference Exception dramas

Daniel Paull dlp at fractaltechnologies.com
Wed May 21 09:46:46 CEST 2003


Apologies for the lack of subject line on my previous post.  This is a
repost of my previous message.

-----Original Message-----
From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On
Behalf Of Daniel Paull
Sent: Wednesday, 21 May 2003 3:37 PM
To: c++-sig at python.org
Subject: [C++-sig] (no subject)

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.

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?

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

Thanks,

Daniel Paull



_______________________________________________
C++-sig mailing list
C++-sig at python.org
http://mail.python.org/mailman/listinfo/c++-sig





More information about the Cplusplus-sig mailing list