Memory Leaks in Python with C API -


i'm trying integrate few c functions have written python , running issues.

here code

static pyobject* foo(pyobject *self,pyobject *args, pyobject *keywds) {  int numitems; pyobject *data_in; pyobject *data_out;   pyobject *itemobj;  int bytesperitem = 1 uint8_t  data[8][544];    static char    *kwlist[] = {"data_in","data_out", null};  if (!pyarg_parsetupleandkeywords(args, keywds, "o!o!",                                  kwlist, &pylist_type, &data_in, &pylist_type, &data_out) {     return null; }   if (!pylist_size(data_in))  {     pyerr_setstring(pyexc_valueerror, "invalid data buffer size");     return null;  }  else  {     numitems = pylist_size(data_in);  } int i; (i=0; < numitems*bytesperitem; += bytesperitem) {     itemobj = pylist_getitem(data_in, i/bytesperitem);     if (!itemobj)     {         return null;     }     switch (bytesperitem)     {         case 1:               *(*(data)+i) =pylong_asunsignedlong(itemobj) & 0xff;              break;          default:             break;     }  }  //do stuff in c data,    //return data python int total_bytes = 8*544  int cwind = 0; while(cwind<(total_bytes)) {     switch (bytesperitem)     {         case 1:             itemc = *(*(data)+cwind); //return multi-dimensional array...             break;           default:             break;     }     itemobj = pylong_fromunsignedlong(itemc);     if (!itemobj)     {         return null;     }     py_incref(itemobj);     pylist_append(data_out, itemobj);     {         py_decref(itemobj);     }     cwind += bytesperitem; } //-------------------------------------------------------------------------     py_decref(data_out); py_decref(data_in);  py_incref(py_true); return py_true; } 

what doing wrong? i'm more of hardware guy, stuff new me.

you leaked reference pylong here (and since it's in loop, leak quite number of references pylongs):

itemobj = pylong_fromunsignedlong(itemc); if (!itemobj) {     return null; } py_incref(itemobj); pylist_append(data_out, itemobj); {     py_decref(itemobj); } cwind += bytesperitem; 

in first line, fresh reference pylong; incref it, append list (and unlike other pylist methods index , set methods, pylist_append not steal reference item, list has own reference), decref (undoing incref). original reference pylong_fromunsignedlong gave never decref-ed away, , replace reference on next loop, leak int/long; it's not complete leak until list created goes away (removing last accessible reference int/long), reference counter off-by-one loop reassigns itemobj on next go around leaked immediately.


Comments