[Pyrex] How does pyrex manage memory that is malloced, realloced, etc.

len-l at telus.net len-l at telus.net
Mon Jun 27 21:49:10 CEST 2005


On 27 Jun 2005 at 10:10, Nathaniel Haggard wrote:

> It seems that this is also ok then:
> 
> cdef extern struct1 * alloc_struct()
> cdef extern free(void *ptr)
> 
> cdef class A:
>     struct1 *s
> 
> def __init__(self):
>      self.s = alloc_struct()
> 

No, the NULL check is still needed in the __init__ method. It prevents
struct1 having its value replaced by a second call to __init__ on
an existing classA object. There is nothing to stop someone from
doing:

a = classA
a.__init__()

But it is unnecessary with the __new__ method since:

a.__new__()

will return a new instance of classA while leaving 'a' untouched.

> def __dealloc__(self):
>     free(self.s)
> 
> 
> A program like this is segfaulting, I'll try to get a minimal example
> working so I can post it.  How do you use gdb with shared objects to
> track down where a segfault is happening.  The backtrace is not
> showing much.
> 
> I run gdb python
> import teststring
> 
> gdb> r
> segfault
> 
> gdb> bt
> 
> #56 0x4012105c in ?? () from /usr/lib/libpython2.3.so.1.0
> #57 0x00000006 in ?? ()
> #58 0x40103e48 in _Py_abstract_hack () from /usr/lib/libpython2.3.so.1.0
> #59 0xbfffe208 in ?? ()
> #60 0x4007452c in PyTuple_New () from /usr/lib/libpython2.3.so.1.0
> 

I do not know much about gbd, but would assume having a debug version
of libpython2.3.so.1.0 would help. I would put some print statements into
the Pyrex module to try and narrow down where the segfault is happening.

> 
> On 6/26/05, len-l at telus.net <len-l at telus.net> wrote:
> > On 26 Jun 2005 at 15:19, Andreas Kostyrka wrote:
> > 
> > > Am Freitag, den 24.06.2005, 17:14 -0600 schrieb Nathaniel Haggard:
> > > > An extension that declares a pointer to a struct
> > > >
> > > > cdef class A:
> > > >        struct1 *s
> > > >
> > > > Also contains a method that wraps a C function that allocates memory.
> > > >
> > > > def init_struc1:
> > > >       self.s = c_init()
> > > >
> > > > Is the memory assigned to self.s safe from overwrites?  How does pyrex
> > > > handle the allocated memory?
> > >
> > > Well, such as this
> > >
> > > A().init_struct()
> > >
> > > would leak memory.
> > >
> > > To demonstrate a correct way:
> > >
> > > cdef class MyBuffer:
> > >     cdef char *buffer
> > >
> > >     def __init__(self):
> > >         if self.buffer == NULL: # init can be called multiple times
> > >             self.buffer = malloc(128)
> > >
> > 
> > The self.buffer = malloc(128) should be done in a __new__ method. This is called
> > only once when the object is actually created, so there is not need to check if
> > buffer is NULL first. It is where all internal C attributes should be initialised.
> > Method __new__  is explained in the "Special Methods of Extension Types" section
> > of the the Pyrex doc.
> > 
> > One warning though. There was some talk of making the Pyrex __new__
> > more like a Python __new__, so code may have to be changed later before the
> > final release of Pyrex.
> > 

Lenard Lindstrom
<len-l at telus.net>




More information about the Pyrex mailing list