[C++-sig] Re: The "return always existing pointer throws dangling error" problem

David Abrahams dave at boost-consulting.com
Tue Oct 21 22:30:50 CEST 2003


"Niall Douglas" <s_sourceforge at nedprod.com> writes:

> Just run into this one myself whereby when querying a FXObject 
> subclass for its metadata (a FXMetaClass) it throws "attempt to 
> return dangling pointer". I've read Dave's comments at 
> http://mail.python.org/pipermail/c++-sig/2003-August/005288.html & 
> http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1781761 and I 
> was wondering, surely it is fairly trivial for BPL to know when a 
> python object holding a reference to a C++ thing is holding it in a 
> non-ownership way?
>
> Let me clarify: From what I understand, most return policies destroy 
> their associated C++ object instance when its python representation 
> expires. Mostly that's a copy of the C++ object instance and when 
> this is the case, the throwing of the error is correct.
>
> However, if the object instance was allocated by new (and thus its 
> policy was manage_new_object), 

Objects don't have call policies; those are associated with
methods/functions.

> then doesn't that strongly imply that the receiving object 
> takes ownership of a newed pointer as well

What do you mean by "receiving object?"  If you mean *this in some
member function:

       void X::f(Y*) {...}

where the Python Y object was created by returning a pointer with the
manage_new_object policy, then no it does not.  Objects held by
pointer or by value are equivalent from the Python side and you can
easily have both for objects of the same type.  If the "taking
ownership" behavior of called methods depended on how the source
object was held, reliability would be horribly compromised.

> because the return policy setting is an artifact of how the C++ code
> works? Therefore in this situation auto_ptr style transference would
> be more useful.

Whether or not auto_ptr-style transference is appropriate is a
property of the called function, not its parameters.  Sorry, if you
want that, make the function (or a thin wrapper) take an auto_ptr
parameter.

When Daniel and I finish the langbinding integration, all C++ objects,
even those *copied* into Python objects, will be held via a pointer to
dynamically-allocated memory so that ownership transfer semantics
will always be available (unless shared_ptr is used, I guess).
However, that will be selectable by a policy on the called function,
not as a function of how the argument is created.

> return_internal_reference is also different - if you attach lifetime 
> to self which most do, then when a virtual override in python returns 
> an internal reference 

?? huh ??
A virtual override in Python can only return a Python object.
There's no such thing as an "internal reference" in that context.

> to either C++ or python code invoking that function

When a virtual function overridden in Python is invoked from Python,
C++ and BPL are never involved.  The function is simply looked up and
called in the usual Python way.  When invoked from C++, the call
policies are never involved, since they only apply to wrapped C++
functions and a Python function is actually being called.

> surely BPL is attaching the lifetime of the internal reference to
> the "self" instance and not to the temporary object created during
> call_method?  Therefore surely the error is reporting the wrong
> thing dangling?

Given everything I've written above, what you're saying makes no
sense to me.

> Lastly looking through the docs I encountered a thing called ptr<> 
> which while it appears to help me in C++

How, and with what problem?

> if I were to subclass 
> FXObject with my own class in python (whereupon I must provide my own 
> custom FXMetaClass to describe it) I'd be smack bang right back into 
> problem-land.
>
> Thoughts? 

More details about your problem are needed.  My suggestion: for the
time-being, stop trying to second-guess the design of Boost.Python and
just describe what you're trying to do with a *minimal example*.  If
we can't come up with a good solution, then we can talk about design
changes.

> I appreciate that this has been addressed before, and that Dave who
> is <censored> has said he's not sure about the correct
> solution.  But I can't see how BPL doesn't know where one of its own
> pointer containers got its pointer from?

I'm not sure whether "where it came from" is relevant, but I guess
we'll see.

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





More information about the Cplusplus-sig mailing list