Memory leaks

ioadler at my-deja.com ioadler at my-deja.com
Thu Jul 13 18:22:39 EDT 2000


In article <8F6667253gmcmhypernetcom at 199.171.54.154>,
  gmcm at hypernet.com (Gordon McMillan) wrote:
> Ingo Adler wrote:
>
> [strange leaks in SWIG'd code]
>
> >I have some simple Python-Code which generated memory leaks (ca. 4MB):
> >(The real code is more complicated, but I could strip it down to this
> >simple example = the smallest example with the memory leak.)
> >//---------------------------
> >x = X()
> >
> >for i in range(100000):
> >    y = x.getY()
> >    y.getNumber()
> >//---------------------------
>
> Doing things in the "obvious" way from your (snipped) incomplete code, I
> get no leak when using MSVC 5.
>
> - Gordon

Hi Gordon,

Finally, I reproduced the leaks under the control of "Code Guard", which can
list them.

For every call in the loop there is an entry like this (I translated it to
English):

Error 00175. 0x300010 (Thread 0xFFE455D5):
Ressource-Leak: memory block (0x2732848) has never been released

memory block (0x02732848) [Size: 40 Byte] was allocated with malloc
call stack:
   0x004AECDD(=FORTUNA.EXE:0x01:0ADCDD) \Python\Objects\stringobject.c#145
   0x0044BE99(=FORTUNA.EXE:0x01:04AE99) \src\fortuna_wrap.c#769
   0x0044F969(=FORTUNA.EXE:0x01:04E969) \src\fortuna_wrap.c#1824
   0x0046B9F9(=FORTUNA.EXE:0x01:06A9F9) \Python\Python\ceval.c#2359
   0x0046B892(=FORTUNA.EXE:0x01:06A892) \Python\Python\ceval.c#2324
   0x0045EDBE(=FORTUNA.EXE:0x01:05DDBE) \Python\bltinmodule.c#126

That makes 40*100000 = 4 MB as I measured roughly before.

fortuna_wrap.c is the code generated by swig:

...

SWIGSTATICRUNTIME(PyObject *)

SWIG_NewPointerObj(void *ptr, _swig_type_info *type) {

  char result[512];

  PyObject *robj;

  if (!ptr) {

    Py_INCREF(Py_None);

    return Py_None;

  }

#ifdef SWIG_COBJECT_TYPES

  robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, type->name, NULL);

#else

  SWIG_MakePtr(result,ptr,type);

// line 769
  robj = PyString_FromString(result);

#endif

  return robj;

}


...

#define Y_getX(_swigobj)  (_swigobj->getX()) static PyObject
*_wrap_Y_getX(PyObject *self, PyObject *args) {  Y  *_arg0;  PyObject 
*_resultobj,*_argo0=0;	X  *_result;  self = self; 
if(!PyArg_ParseTuple(args,"O:Y_getX",&_argo0))	return NULL;  if
((SWIG_ConvertPtr(_argo0,(void **) &_arg0,SWIGTYPE_Y_p,1)) == -1) return
NULL;  _result = (X *)Y_getX(_arg0);

// line 1824
    _resultobj = SWIG_NewPointerObj((void *) _result, SWIGTYPE_X_p);
    return _resultobj;
}

...


So it happens in PyString_FromString - but only with this loop (= both
functions in the loop).

Any suggestions?

Ingo





Sent via Deja.com http://www.deja.com/
Before you buy.



More information about the Python-list mailing list