[Qgis-developer] QgsRubberBand RuntimeError: underlying C/C++ object has been deleted

Vincent Mora vincent.mora at oslandia.com
Thu Feb 13 11:17:18 PST 2014

On 13/02/2014 14:22, Martin Dobias wrote:
> On Thu, Feb 13, 2014 at 7:56 PM, Denis Rouzaud <denis.rouzaud at gmail.com> wrote:
>>> 2) If a SIP wrapper class A has a member class B and an instance of A
>>> is created in Python,  B member is referenced and reference to A is
>>> deleted is it the A instance deleted by GC including B (which is still
>>> referenced)?
>>> C++: class A { B b; }
>>> SIP: class A { B b; }
>>> Python:
>>> a = A()
>>> b = a.b
>>> a = None
>>> # garbage collector
>>> a and b were deleted?
>> I would say yes too. But, I would ask confirmation to people more aware than
>> me. There should be some reading this ;)
> My understanding is following: with the line "a = None" the reference
> count to SIP wrapper of A gets to zero. Because the object is owned by
> Python (it was created in Python and the ownership was not transferred
> to c++), also the underlying C++ object will be deleted. As far as I
> know, "b" will still reference to SIP wrapper of B which in turn
> references C++ object that has been deleted in the meanwhile. Using
> "b" will may lead to crashes (or just strange behavior). If the class
> "B" had a virtual destructor, the SIP wrapper for B (which is subclass
> of B) should be at least be notified that the instance is going to be
> deleted - so when trying to use "b" again, SIP can at least raise the
> exception instead of crashing.
> The above is my expectation of what happens, I have not actually tried that.
> Martin
> _______________________________________________
> Qgis-developer mailing list
> Qgis-developer at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/qgis-developer
I found that a bit surprising, so I did the test, an actually python+sip 
do a pretty good job in ref counting (at least for the mentioned classes 
which are pretty simple)

I Added a dtor to QgsSnappingResult to see when it's called:

    ~QgsSnappingResult(){std::cout << __PRETTY_FUNCTION__ << "\n";}

And the little script:

    from qgis.core import *

    print "try to del r while p is still referencing one of it's members"
    r = QgsSnappingResult()
    p = r.snappedVertex
    del r
    print "it's not deleted yet"
    print "delete the referencing guy"
    del p
    print "it's deleted"

    print "try to del r (i.e. without anyone referencing anything)"
    r = QgsSnappingResult()
    del r
    print "it's deleted"


    try to del r while p is still referencing one of it's members
    it's not deleted yet
    delete the referencing guy
    it's deleted
    try to del r (i.e. without anyone referencing anything)
    it's deleted

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20140213/cedcbba0/attachment-0001.html>

More information about the Qgis-developer mailing list