So, shoving cdef classes into C++ STL containers *seems* to work (when
compiling with language='c++' of course) but with some strange side
effects. I'm getting quite a strange crash (seg fault), which only
happens the second time I call the function that does it. It seems to
be related to deque, replacing that with a Python deque is fine.
Replacing it with a C++ STL vector still yields the same problem.
On Sep 12, 2012 7:56 PM, "David Warde-Farley" <d.warde.far...@gmail.com>
wrote:
> Hello everyone,
> So, shoving cdef classes into C++ STL containers *seems* to work (when
> compiling with language='c++' of course) but with some strange side
> effects. I'm getting quite a strange crash (seg fault), which only
> happens the second time I call the function that does it. It seems to
> be related to deque, replacing that with a Python deque is fine.
> Replacing it with a C++ STL vector still yields the same problem.
On Wed, Sep 12, 2012 at 11:17 PM, Robert Bradshaw <rober...@gmail.com> wrote:
> Sticking Python objects in c++ containers doesn't work as they don't do
> reference counting... This should be a compile error.
Welp, that explains it. I figured there might be some voodoo going on
that made it possible to refcount cdef classes in STL containers given
that it magically worked (and seems to work without crashing in other
cases).
On Wed, Sep 12, 2012 at 8:37 PM, David Warde-Farley
<d.warde.far...@gmail.com> wrote:
> On Wed, Sep 12, 2012 at 11:17 PM, Robert Bradshaw <rober...@gmail.com> wrote:
>> Sticking Python objects in c++ containers doesn't work as they don't do
>> reference counting... This should be a compile error.
> Welp, that explains it. I figured there might be some voodoo going on
> that made it possible to refcount cdef classes in STL containers given
> that it magically worked (and seems to work without crashing in other
> cases).
It's storing borrowed references, so it'll work as long as something
else in Python-space keeps it alive (which is, as evidenced, a rather
precarious situation to be in).
On Thu, Sep 13, 2012 at 12:02 AM, Robert Bradshaw <rober...@gmail.com> wrote:
> It's storing borrowed references, so it'll work as long as something
> else in Python-space keeps it alive (which is, as evidenced, a rather
> precarious situation to be in).
Indeed. I'm confused, though: in the example I've given, all 4 nodes
have references not only to each other but in the method scope of
test_dfs. It's unclear to me how or why they'd be garbage collected
(or decref'd to 0) before test_dfs() finished (since it's a call in
the last line of test_dfs where the crash takes place).
> On Thu, Sep 13, 2012 at 12:02 AM, Robert Bradshaw <rober...@gmail.com> wrote:
>> It's storing borrowed references, so it'll work as long as something
>> else in Python-space keeps it alive (which is, as evidenced, a rather
>> precarious situation to be in).
> Indeed. I'm confused, though: in the example I've given, all 4 nodes
> have references not only to each other but in the method scope of
> test_dfs. It's unclear to me how or why they'd be garbage collected
> (or decref'd to 0) before test_dfs() finished (since it's a call in
> the last line of test_dfs where the crash takes place).
If you want to do this, write an auto_ptr-like class, a class overloading operator* and operator->, let's call it pyptr, which has a PyObject* member but does INCREF on construction and DECREF on destruction.
Then simply create std::vector<pyptr> rather than std::vector<PyObject*>.
This *should* work, but to my knowledge there isn't any code available already, so please report back if you do this and perhaps we can include the pyptr class with Cython.
> On 09/13/2012 07:26 AM, David Warde-Farley wrote:
>> On Thu, Sep 13, 2012 at 12:02 AM, Robert Bradshaw <rober...@gmail.com>
>> wrote:
>>> It's storing borrowed references, so it'll work as long as something
>>> else in Python-space keeps it alive (which is, as evidenced, a rather
>>> precarious situation to be in).
>> Indeed. I'm confused, though: in the example I've given, all 4 nodes
>> have references not only to each other but in the method scope of
>> test_dfs. It's unclear to me how or why they'd be garbage collected
>> (or decref'd to 0) before test_dfs() finished (since it's a call in
>> the last line of test_dfs where the crash takes place).
> If you want to do this, write an auto_ptr-like class, a class
> overloading operator* and operator->, let's call it pyptr, which has a
> PyObject* member but does INCREF on construction and DECREF on destruction.
> Then simply create std::vector<pyptr> rather than std::vector<PyObject*>.
> This *should* work, but to my knowledge there isn't any code available
> already, so please report back if you do this and perhaps we can include
> the pyptr class with Cython.
In fact, once std::vector<pyptr> works really well, it should be rather easy to build it into Cython and support "std::vector<object>" as a syntax for it. Not volunteering though.
<d.s.seljeb...@astro.uio.no> wrote:
> On 09/13/2012 07:26 AM, David Warde-Farley wrote:
>> On Thu, Sep 13, 2012 at 12:02 AM, Robert Bradshaw <rober...@gmail.com>
>> wrote:
>>> It's storing borrowed references, so it'll work as long as something
>>> else in Python-space keeps it alive (which is, as evidenced, a rather
>>> precarious situation to be in).
>> Indeed. I'm confused, though: in the example I've given, all 4 nodes
>> have references not only to each other but in the method scope of
>> test_dfs. It's unclear to me how or why they'd be garbage collected
>> (or decref'd to 0) before test_dfs() finished (since it's a call in
>> the last line of test_dfs where the crash takes place).
> If you want to do this, write an auto_ptr-like class, a class overloading
> operator* and operator->, let's call it pyptr, which has a PyObject* member
> but does INCREF on construction and DECREF on destruction.
> Then simply create std::vector<pyptr> rather than std::vector<PyObject*>.
> This *should* work, but to my knowledge there isn't any code available
> already, so please report back if you do this and perhaps we can include the
> pyptr class with Cython.
I was about to suggest exactly this. Syntax is a good question though,
but perhaps "std::vector<object>" would be sufficient.
On Thursday, September 13, 2012 8:59:43 AM UTC-7, Robert Bradshaw wrote:
> On Thu, Sep 13, 2012 at 1:58 AM, Dag Sverre Seljebotn > <d.s.se...@astro.uio.no <javascript:>> wrote: > > On 09/13/2012 07:26 AM, David Warde-Farley wrote:
> >> On Thu, Sep 13, 2012 at 12:02 AM, Robert Bradshaw <robe...@gmail.com<javascript:>>
> >> wrote:
> >>> It's storing borrowed references, so it'll work as long as something > >>> else in Python-space keeps it alive (which is, as evidenced, a rather > >>> precarious situation to be in).
> >> Indeed. I'm confused, though: in the example I've given, all 4 nodes > >> have references not only to each other but in the method scope of > >> test_dfs. It's unclear to me how or why they'd be garbage collected > >> (or decref'd to 0) before test_dfs() finished (since it's a call in > >> the last line of test_dfs where the crash takes place).
> > If you want to do this, write an auto_ptr-like class, a class > overloading > > operator* and operator->, let's call it pyptr, which has a PyObject* > member > > but does INCREF on construction and DECREF on destruction.
> > Then simply create std::vector<pyptr> rather than > std::vector<PyObject*>.
> > This *should* work, but to my knowledge there isn't any code available > > already, so please report back if you do this and perhaps we can include > the > > pyptr class with Cython.
> I was about to suggest exactly this. Syntax is a good question though, > but perhaps "std::vector<object>" would be sufficient.
> On Thursday, September 13, 2012 8:59:43 AM UTC-7, Robert Bradshaw wrote:
>> On Thu, Sep 13, 2012 at 1:58 AM, Dag Sverre Seljebotn wrote: >>> On 09/13/2012 07:26 AM, David Warde-Farley wrote: >>>> On Thu, Sep 13, 2012 at 12:02 AM, Robert Bradshaw wrote:
>>>>> It's storing borrowed references, so it'll work as long as something >>>>> else in Python-space keeps it alive (which is, as evidenced, a rather >>>>> precarious situation to be in).
>>>> Indeed. I'm confused, though: in the example I've given, all 4 nodes >>>> have references not only to each other but in the method scope of >>>> test_dfs. It's unclear to me how or why they'd be garbage collected >>>> (or decref'd to 0) before test_dfs() finished (since it's a call in >>>> the last line of test_dfs where the crash takes place).
>>> If you want to do this, write an auto_ptr-like class, a class >>> overloading >>> operator* and operator->, let's call it pyptr, which has a PyObject* >>> member but does INCREF on construction and DECREF on destruction.
>>> Then simply create std::vector<pyptr> rather than >>> std::vector<PyObject*>.
>>> This *should* work, but to my knowledge there isn't any code available >>> already, so please report back if you do this and perhaps we can include >>> the pyptr class with Cython.
>> I was about to suggest exactly this. Syntax is a good question though, >> but perhaps "std::vector<object>" would be sufficient.