[Matrix-SIG] Memory leaks in netCDFmodule?

Joe Van Andel vanandel@ucar.edu
Wed, 16 Jun 1999 14:56:33 -0600


This is a multi-part message in MIME format.
--------------27E54049BB21808E8F01A259
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I'm using Konrad Hinsen's netCDFmodule-1.0.3 with Python 1.5.2 and
Numeric Python (LLNLDistribution11).  Now that my application is nearly
completed, I'm trying to find and fix the various memory leaks, such
that I can process an arbitrary number of files without running out of
memory.

One of the leaks is associated with the netCDFmodule.  When I open a
file, e.g:

a1file=NetCDFFile(file, 'r')

the "C" routine netcdf_variable_new is called for each variable.
However, when I'm done with this file, the memory for these variables
should go away, and it doesn't.
(PyNetCDFVariableObject_dealloc is never called.)

  
I did find an interesting workaround.

Immediately after creating a netCDF file object, 
>>> sys.getrefcount(a1file)
12

Reading the source code, some of these references are caused by creating
the variables that reside in the file.  If I explicitly free each
variable, using code like:

    for v in a1file.variables.keys():
        a1file.variables[v] = None

Would everyone agree that the <netcdf>.close() method should explicitly
free these variables, so all memory is recovered?




Thanks much.

I've attached a context diff that fixes 1 memory leak in netcdfmodule.c,
I'm still chasing others.




-- 
Joe VanAndel  	          
National Center for Atmospheric Research
http://www.atd.ucar.edu/~vanandel/
Internet: vanandel@ucar.edu
--------------27E54049BB21808E8F01A259
Content-Type: text/plain; charset=us-ascii;
 name="cdiff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cdiff"

*** netcdfmodule.orig	Wed Jun 16 14:52:57 1999
--- netcdfmodule.c.clean	Wed Jun 16 14:54:00 1999
***************
*** 171,176 ****
--- 171,177 ----
       int nattrs;
  {
    char name[MAX_NC_NAME];
+ 
    nc_type type;
    int length;
    int py_type;
***************
*** 186,191 ****
--- 187,193 ----
            ncattget(fileid, varid, name, s);
            s[length] = '\0';
            string = PyString_FromString(s);
+           free(s);
            if (string != NULL) {
                PyDict_SetItemString(attributes, name, string);
                Py_DECREF(string);
***************
*** 273,278 ****
--- 275,282 ----
  PyNetCDFFileObject_dealloc(self)
       PyNetCDFFileObject *self;
  {
+ 
+     
    if (self->open)
      PyNetCDFFile_Close(self);
    Py_XDECREF(self->dimensions);
***************
*** 809,816 ****
  {
    if (self->dimids != NULL)
      free(self->dimids);
!   if (self->name != NULL)
      free(self->name);
    Py_XDECREF(self->file);
    PyMem_DEL(self);
  }
--- 813,822 ----
  {
    if (self->dimids != NULL)
      free(self->dimids);
!   if (self->name != NULL) {
        free(self->name);
+   }
+   
    Py_XDECREF(self->file);
    PyMem_DEL(self);
  }
***************
*** 827,835 ****
--- 833,843 ----
       int *dimids;
       int nattrs;
  {
+   
    PyNetCDFVariableObject *self;
    int recdim;
    int i;
+   
    if (check_if_open(file, -1)) {
      self = PyObject_NEW(PyNetCDFVariableObject, &PyNetCDFVariable_Type);
      if (self == NULL)

--------------27E54049BB21808E8F01A259--