dbTalk Databases Forums  

i don't understand why my application doesn't free memory

comp.databases.berkeley-db comp.databases.berkeley-db


Discuss i don't understand why my application doesn't free memory in the comp.databases.berkeley-db forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
stefan
 
Posts: n/a

Default i don't understand why my application doesn't free memory - 02-10-2005 , 11:16 PM






hey

i've written a small db-app that checks two dbs that are primary and
secondary index to each other for consistency - while running i can
see in the top command that my app allocates a lot of memory but
doesn't free it. i really dont understand why, as i am freeing all
data that i get from the db after usage.
seems like i leak in a basic understanding of how berkeley-db handles
memory!?

thanx for your help
stefan

CODE:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <db.h>


typedef struct {
unsigned section:4; /* 0 - meta
1 - title
2 - heading
3 - body
4 - link
*/
unsigned position:16;
unsigned font_size:3;
unsigned add_on1:1; /* markup like <b><big><u> */
unsigned add_on2:1; /* capitalized word */
unsigned add_on3:1; /* unused.. */
unsigned add_on4:1;
unsigned add_on5:1;
unsigned add_on6:1;
unsigned add_on7:1;
unsigned add_on8:1;
unsigned add_on9:1;
} hds_word_flags;

DBC *dbcp1, *dbcp2;
DBT key1, key2, data1, data2;
DB *dbp1, *dbp2;
int ret;
int ekey, edata;
int i;
int hit_num;
hds_word_flags *word_flags, *flags;
int *hits1, *hits2;
int found_entry, correct_hits, correct_section;

int main(int argc,void *argv[])
{
if ( 0!= (ret = db_create(&dbp1, NULL, 0)))
{
return(-1);
}

if ( 0!= (ret = db_create(&dbp2, NULL, 0)))
{
return(-1);
}

if(0!=(ret=dbp1->set_flags(dbp1, DB_DUP)))
{
return(-1);
}

if(0!=(ret=dbp2->set_flags(dbp2, DB_DUP)))
{
dbp1->close(dbp1,0);
return(-1);
}

if( 0 != (ret=dbp1->open(dbp1, NULL, argv[1], NULL
, DB_HASH, DB_CREATE | DB_THREAD, 0664)))
{
dbp1->close(dbp1,0);
dbp2->close(dbp2,0);
return(-1);
}

if( 0 != (ret=dbp2->open(dbp2, NULL, argv[2], NULL
, DB_HASH, DB_CREATE | DB_THREAD, 0664)))
{
dbp1->close(dbp1,0);
dbp2->close(dbp2,0);
return(-1);
}

/* initialize the DBT structures by clearing their data */
memset(&key1, 0, sizeof(key1));
memset(&data1, 0, sizeof(data1));
key1.flags=DB_DBT_MALLOC;
data1.flags=DB_DBT_MALLOC;
memset(&key2, 0, sizeof(key2));
memset(&data2, 0, sizeof(data2));
key2.flags=DB_DBT_MALLOC;
data2.flags=DB_DBT_MALLOC;

/* get a cursor for the first db */
if ((ret = dbp1->cursor(dbp1, NULL, &dbcp1, 0)) != 0)
{
dbp1->close(dbp1,0);
dbp2->close(dbp2,0);
return(-1);
}

printf("checking %s to %s:\n", argv[1], argv[2]);
/* iterate ones over the first db */
while((ret = dbcp1->c_get(dbcp1, &key1, &data1, DB_NEXT)) == 0)
{
/* get a cursor for the second db */
if ((ret = dbp2->cursor(dbp2, NULL, &dbcp2, 0)) != 0)
{
dbcp1->c_close(dbcp1);
dbp1->close(dbp1,0);
dbp2->close(dbp2,0);
return(-1);
}

ekey=*(int*)key1.data;
edata=*(int*)data1.data;
hits1=(int*)data1.data;

/* iterate over the second db */
found_entry=0;
correct_hits=0;
correct_section=1;

key2.data=&edata;
key2.size=sizeof(int);
//printf("1\n");
if((ret = dbcp2->c_get(dbcp2, &key2, &data2, DB_SET)) == 0)
{
/* compare the entries */
if(ekey==*(int*)data2.data)
{
found_entry=1;

/* check the hits */
hits2=(int*)data2.data;
if(0==memcmp(&hits1[1],&hits2[1],data1.size-sizeof(int)))
{
correct_hits=1;
}

/* check the range of the section value */
if(correct_hits)
{
flags=(hds_word_flags*)&hits1[1];

/* calculate how many hits are there */
hit_num=(int)(data1.size-sizeof(int))/sizeof(hds_word_flags);

for(i=0;i<hit_num;i++)
{
if( (flags[i].section<0) || (flags[i].section>4))
{
correct_section=0;
}
}
}
}

/* free resources */
free(data2.data);
}
//printf("2\n");
if(ret==0)
{
//printf("3\n");
while((found_entry==0) && ((ret = dbcp2->c_get(dbcp2, &key2,
&data2, DB_NEXT_DUP)) == 0))
{

/* compare the entries */
if(ekey==*(int*)data2.data)
{
found_entry=1;

/* check the hits */
hits2=(int*)data2.data;
if(0==memcmp(&hits1[1],&hits2[1],data1.size-sizeof(int)))
{
correct_hits=1;
}

/* check the range of the section value */
if(correct_hits)
{
flags=(hds_word_flags*)&hits1[1];

/* calculate how many hits are there */
hit_num=(int)(data1.size-sizeof(int))/sizeof(hds_word_flags);

for(i=0;i<hit_num;i++)
{
if( (flags[i].section<0) || (flags[i].section>4))
{
correct_section=0;
}
}
}
}

/* free resources */
free(data2.data);
}
}
dbcp2->c_close(dbcp2);
free(data1.data);
free(key1.data);

if(!found_entry)
{
printf(" corrupted index for %s at key: %d and data: %d\n",
argv[2], ekey, edata);
}
else if(!correct_hits)
{
printf(" wrong hits for %s at key: %d and data: %d\n", argv[2],
ekey, edata);
}
else if(!correct_section)
{
printf(" invalid value in section flag for %s at key: %d and data:
%d\n", argv[2], ekey, edata);
}
}

printf("finished\n\n");
dbcp1->c_close(dbcp1);
dbp1->close(dbp1,0);
dbp2->close(dbp2,0);

printf("exiting\n");

exit(0);
}

Reply With Quote
  #2  
Old   
Michael Cahill
 
Posts: n/a

Default Re: i don't understand why my application doesn't free memory - 02-14-2005 , 07:54 PM






Hi Stefan,

I'm not exactly sure where the memory is going, but I have a couple of
suggestions:

* you set the DB_DBT_MALLOC flag on key2, but you don't free that data
anywhere. It looks like DB_DBT_USERMEM might better match your
intentions.

* this application might benefit from DB_DBT_REALLOC rather than
DB_DBT_MALLOC on the remaining DBTs. That way you can just free them
all once at the end of your code rather than each time through each
loop.

Regards,
Michael.


Reply With Quote
  #3  
Old   
Michael Cahill
 
Posts: n/a

Default Re: i don't understand why my application doesn't free memory - 02-14-2005 , 07:56 PM



Hi Stefan,

One more thing: you set DB_THREAD on open in this example. If your
application is not in fact using handles in multiple threads, you can
drop that flag and all of the DBT memory flags, and DB will free the
memory for you when the cursors are closed, simplifying things quite a
bit.

Regards,
Michael.


Reply With Quote
  #4  
Old   
stefan
 
Posts: n/a

Default Re: i don't understand why my application doesn't free memory - 02-20-2005 , 10:09 PM



Hey Michael,

changing the configuration to DB_DBT_REALLOC solved the problem!
Thank you very much!!

Ciao Stefan

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.