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);
} |