From: Graeme S. <gra...@ma...> - 2010-07-20 12:34:44
|
Hi Pierre, On 10-07-19 01:40 PM, Pierre-Henri Wuillemin wrote: > Hi all, > > I have an error that I do not understand. [swig 1.3 or swig 2.0] : a method > that returns (*this) may or may not crash, depending on how the object has > been created. <snip> > ========================iPython session > In [1]: import smallTest > > In [2]: a=smallTest.A() > a new A is born > > In [3]: a.inc(2).inc(3) > Out[3]:<smallTest.A; proxy of<Swig Object of type 'A *' at 0x2c580c0> > > > In [4]: a.get() > Out[4]: 5 > > In [5]: b=smallTest.A().inc(2).inc(3) > a new A is born > Erreur de segmentation > ============================= > > Do you have any idea about this behaviour ? > > Thanks in advance for your answers. You might want to think about how your class interacts with reference-counting and garbage collection in Python. I've added a destructor to help clarify: #include <iostream> class A { private: int x; public: A():x(0) {std::cout<<"a new A is born"<<std::endl;} ~A() {std::cout<<"a new A is mutilated beyond recognition"<<std::endl;} A& inc(int val) {x+=val;std::cout << "inc" << std::endl;return *this;} int get() {return x;} }; Running this, I get >>> import smallTest >>> b = smallTest.A().inc(2).inc(3) a new A is born inc a new A is mutilated beyond recognition inc Segmentation fault (core dumped) The first inc() call leaked a reference to the class that Python didn't know about. After this call, Python decrements its reference count to 0, and the class is garbage collected. The second call causes the segfault. You should be able to stop Python from doing so using SWIG's %ref/%unref mechanisms. cheers, Graeme Smecher |