Re: gdbm memory leak

Steve Clift (clift@ml.csiro.au)
Mon, 13 Mar 1995 02:20:33 GMT

Eric Bouck (ebouck@myhost.subdomain.domain) wrote:
: (apologies if this is a duplicate post)

: The gdbm module seems to have a memory leak.
: The following code demonstrates it:

: import gdbm

: LargeNumber = 5000
: d = gdbm.open ('testdbm', 'w', 0666)
: i = 0
: # this does not leak memory
: while i < LargeNumber:
: d[str(i)] = 'object %d' % i
: i = i + 1
: i = 0
: # this does leak memory
: while i < LargeNumber:
: print d[str(i)]
: i = i + 1

: Does anyone have a fix?

: Eric

It actually has (at least) two memory leaks, one in the fetch routine
and another in the has_key() method The following patch fixes these
and tarts-up a couple of other things.

============================================================================
*** gdbmmodule.c Thu Jan 5 06:10:06 1995
--- gdbmmodule.c Mon Mar 13 12:44:33 1995
***************
*** 61,68 ****
if (dp == NULL)
return NULL;
dp->di_size = -1;
if ( (dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0 ) {
! err_errno(DbmError);
DECREF(dp);
return 0;
}
--- 61,72 ----
if (dp == NULL)
return NULL;
dp->di_size = -1;
+ errno = 0;
if ( (dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0 ) {
! if (errno != 0)
! err_errno(DbmError);
! else
! err_setstr(DbmError, (char *) gdbm_strerror(gdbm_errno));
DECREF(dp);
return 0;
}
***************
*** 117,123 ****
err_setstr(KeyError, GETSTRINGVALUE((stringobject *)key));
return 0;
}
! return newsizedstringobject(drec.dptr, drec.dsize);
}

static int
--- 121,129 ----
err_setstr(KeyError, GETSTRINGVALUE((stringobject *)key));
return 0;
}
! v = newsizedstringobject(drec.dptr, drec.dsize);
! free(drec.dptr);
! return v;
}

static int
***************
*** 143,150 ****
"gdbm mappings have string elements only");
return -1;
}
if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
! err_setstr(DbmError, "Cannot add item to database");
return -1;
}
}
--- 149,160 ----
"gdbm mappings have string elements only");
return -1;
}
+ errno = 0;
if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
! if (errno != 0)
! err_errno(DbmError);
! else
! err_setstr(DbmError, (char *) gdbm_strerror(gdbm_errno));
return -1;
}
}
***************
*** 192,203 ****
register dbmobject *dp;
object *args;
{
! datum key, val;

if (!getargs(args, "s#", &key.dptr, &key.dsize))
return NULL;
! val = gdbm_fetch(dp->di_dbm, key);
! return newintobject(val.dptr != NULL);
}

static struct methodlist dbm_methods[] = {
--- 202,212 ----
register dbmobject *dp;
object *args;
{
! datum key;

if (!getargs(args, "s#", &key.dptr, &key.dsize))
return NULL;
! return newintobject((long) gdbm_exists(dp->di_dbm, key));
}

static struct methodlist dbm_methods[] = {
***************
*** 254,260 ****
iflags = GDBM_NEWDB;
else {
err_setstr(DbmError,
! "Flags should be one of 'r', or 'w'");
return 0;
}
return newdbmobject(name, iflags, mode);
--- 263,269 ----
iflags = GDBM_NEWDB;
else {
err_setstr(DbmError,
! "Flags should be one of 'r', 'w', 'c' or 'n'");
return 0;
}
return newdbmobject(name, iflags, mode);
***************
*** 275,279 ****
if ( DbmError == NULL || dictinsert(d, "error", DbmError) )
fatal("can't define gdbm.error");
}
-
-
--- 284,286 ----
============================================================================

--
----------------------------------------------------------------------------
Steve Clift				   Email: clift@ml.csiro.au
CSIRO Division of Oceanography		   Phone: +61-02-32-5243
Hobart, Tasmania, Australia		   Fax:   +61-02-32-5000
----------------------------------------------------------------------------