SELECT ... INTO and mem leaks!
Posted in 1995
Topics: Storage & Space Management, Error Codes & Troubleshooting, Connectivity: ESQL/C, 4GL & Embedded SQL
I have check out the InformixLink database for somethin on this but have
not seen an adiquate explanation why these following occurs. Also, If any
one has seen this problem before what Version of Informix did you use to
correct it (should I go back to 4.1?) or are there other code work arounds.
I have two main area that are using memory. I tried to follow ALL the
Informix SQL tutorial suggestions and what follows are my solutions.
Here is the code. Using 5.00.UD1 ESQL/C and Online 5.01.UD2.
int restof_dir_info (type, dkey, dst)
EXEC SQL BEGIN DECLARE SECTION;
PARAMETER short type;
PARAMETER char *dkey;
EXEC SQL END DECLARE SECTION;
union dir_type *dst;
{
EXEC SQL BEGIN DECLARE SECTION;
union idb_rec recd;
union i_dir_type *rec;
EXEC SQL END DECLARE SECTION;
memset ((char *)&recd, '\\0', sizeof(recd));
EXEC SQL SELECT * INTO :recd.pat
FROM patient WHERE dir_key MATCHES :dkey;
memcpy((char*)dst, &recd.pat.info, sizeof(struct i_dir_pat));
}
PROBLEM: After the "select * into" statment the program allocates
1K every time.
MY SOLUTION: changed to the following ....
EXEC SQL declare pat_rec_cur cursor for
SELECT * FROM patient WHERE dir_key MATCHES :dkey; EXEC SQL open pat_rec_cur;
EXEC SQL fetch pat_rec_cur into :recd.pat;
Ck_sqlcode;
memcpy((char*)dst, &recd.pat.info, sizeof(struct i_dir_pat));
In this code the program allocates 1K once but never again for this section
of code. Why does this happen? My data structure (recd) is roughly 1K is
size. Why is it not released after leaving the routine. If I make a similar
declare statement for a different record type the system allocates another 1K.
At least in this manner the program will reach a maximume size but will not
crash after sucking up too much memory.
Here's the second example of memory allocation. Some of the frivilous stuff
has been removed.
sprintf (demoquery, Qry[q_stmt].cmd, fld1, fld2);
EXEC SQL prepare qry_dir_id from :demoquery;
Ck_sqlcode;
EXEC SQL declare dir_cursor cursor for qry_dir_id;
Ck_sqlcode;
EXEC SQL open dir_cursor using :expr1;
for(;;)
{
EXEC SQL fetch dir_cursor
into :dir_rec->dir_key, :dir_rec->type, :dir_rec->name,
:dir_rec->extn, :dir_rec->room, :dir_rec->bed,
:dir_rec->dialname,
:dir_rec->btype, :dir_rec->badge;
}
EXEC SQL close dir_cursor;
EXEC SQL free dir_cursor;
EXEC SQL free qry_dir_id; /* <<<<<<<------- */
PROBLEM:
This code section again takes up some chunk of memory and allocates
the same size chunk each time through the routine.
MY SOLUTION:
Don't call the 'free qry_dir_id'. At least this way the routine will
allocate the 1K data structres ones and will not allocate yet another
on each recurring pass through the routine. Again the system grows to a
maximum size and does not crash with an out of memory condition.
After being told by our data base guru (the only person allowed to go to an
informix class from our group) that I should be using 5.00, I reluctantly
did and this memory problem has been my only reward. Thanks! *:-(
After following *ALL* the tutorial examples to the letter and going over
every inch of documentation I had to find this by trial-and-error.
I don't have a good fealling about going to 6.??.
Thanks is advance.
George Follis follis@esd.dl.nec.com
--------------------------------------------------------------------------
The most widely used computer language ....
$*#%"&@+!
--------------------------------------------------------------------------