[Patches] posixmodule.c memory leak patch

Barry Warsaw bwarsaw@python.org
Tue, 11 Apr 2000 18:31:32 -0400 (EDT)


In the process of mem checking my funcattrs patches, I ran across a
memory leak in setup_confname_table() in posixmodule.c.  The cause is
clear: PyDict_SetItemString() borrows ownership of the value object
(i.e. it INCREFs it whether it succeeds or not).  Thus both the
individual int objects and the conf dictionary are all leaked.  This
patch fixes the memory leak (according to Purify) and simplifies the
logic in the meantime.

BTW, Purify reports a bunch of other memory problems which should be
nailed before 1.6 final goes out.  I'll see what I can do about
whacking them.

-Barry

-------------------- snip snip --------------------
Index: posixmodule.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Modules/posixmodule.c,v
retrieving revision 2.129
diff -c -r2.129 posixmodule.c
*** posixmodule.c	2000/03/31 01:26:23	2.129
--- posixmodule.c	2000/04/11 22:21:57
***************
*** 4325,4351 ****
       PyObject *moddict;
  {
      PyObject *d = NULL;
  
      qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
      d = PyDict_New();
!     if (d != NULL) {
!         PyObject *o;
!         size_t i = 0;
  
!         for (; i < tablesize; ++i) {
!             o = PyInt_FromLong(table[i].value);
!             if (o == NULL
!                 || PyDict_SetItemString(d, table[i].name, o) == -1) {
!                 Py_DECREF(d);
!                 d = NULL;
!                 return -1;
              }
!         }
!         if (PyDict_SetItemString(moddict, tablename, d) == -1)
!             return -1;
!         return 0;
      }
!     return -1;
  }
  
  /* Return -1 on failure, 0 on success. */
--- 4325,4350 ----
       PyObject *moddict;
  {
      PyObject *d = NULL;
+     size_t i;
+     int status;
  
      qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
      d = PyDict_New();
!     if (d == NULL)
! 	    return -1;
  
!     for (i=0; i < tablesize; ++i) {
!             PyObject *o = PyInt_FromLong(table[i].value);
!             if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
! 		    Py_XDECREF(o);
! 		    Py_DECREF(d);
! 		    return -1;
              }
! 	    Py_DECREF(o);
      }
!     status = PyDict_SetItemString(moddict, tablename, d);
!     Py_DECREF(d);
!     return status;
  }
  
  /* Return -1 on failure, 0 on success. */