12

I have 2 codes(programs)

Program 1:

//global variables
MYSQL_RES *res_set;
MYSQL_ROW row;
MYSQL *connect;

int main()
{
 connect=mysql_init(NULL);
 mysql_real_connect(connect, NULL, "root", "suvp" ,"Employees" ,0,NULL,0);

 /*Other Code*/

 mysql_free_result(res_set);
 mysql_close(connect);
}

"Other Code" involves a for loop which calls functions that make use of the same res_set for storing results from mysql_store_result. As seen, I call mysql_free_result(res_set); only once at the end of main.

valgrind shows still reachable memory problems in the above case (which I have chosen to ignore). No other leaks are present.

Program 2:

class mysqlClientClass has following private variables,

MYSQL *connect;
MYSQL_RES *res_set; 
MYSQL_ROW row;

Some of the methods are (relevant to my issue),

mysqlClientClass::~mysqlClientClass()
{
if(connect!=NULL)
{   
    mysql_free_result(res_set);
    mysql_close(connect);   
}
}

If the user fails to call closeConnection, the destructor will close it (by checking if connect is set to NULL or no)

void mysqlClientClass::closeConnection()
{
    mysql_free_result(res_set);
    mysql_close(connect);
    connect = NULL;
}

getResults is the only method in the whole code that uses mysql_store_result

void mysqlClientClass::getResults(string iQuery)
{
 /* form query 
    execute Query */

res_set = mysql_store_result(connect);

 /* Do other things */

    mysql_free_result(res_set); // ------------------------>
    res_set = NULL;
    }
}

If i don't free the res_set at the end of the function(and free it in the destructor / close Connection only) and I make several calls to this function valgrind reports,

=10162== LEAK SUMMARY:
==10162==    definitely lost: 312 bytes in 3 blocks
==10162==    indirectly lost: 49,152 bytes in 9 blocks
==10162==      possibly lost: 0 bytes in 0 blocks
==10162==    still reachable: 73,872 bytes in 21 blocks
==10162==         suppressed: 0 bytes in 0 blocks
==10162== Reachable blocks (those to which a pointer was found) are not shown.
==10162== To see them, rerun with: --leak-check=full --show-reachable=yes
==10162== 
==10162== For counts of detected and suppressed errors, rerun with: -v
==10162== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

and it all comes down to mysql_store_result

==10162==    by 0x406C3CA: mysql_store_result (in /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0)
==10162==    by 0x8048E03: mysqlClientClass::getResults(std::string) (mysqlClientClass.cpp:103)

As per the manual page of mysql_store_result

mysql_store_result() reads the entire result of a query to the client, allocates a MYSQL_RES structure, and places the result into this structure.

and it also suggests I should call free_result after use.

This seems to work as documented, in Program 2 (memory leaks when I don't call mysql_free_result) but then why does Program 1 not show any leaks? In Program 1 too I make several calls to mysql_store_result between various functions without freeing each time.

1 Answer 1

-4

You dont need mysql_store_result to obtain data from the query - use callbacks with sqlite3_exec

int ListDataCallback(void *pArg, int argc, char **argv, char **columnNames){
  //cast pArg to your user data pointer
  //argc - count of columns in the result
  //argv - a result field as string

  return 0;
}

void get_data()
{
    char *selectErrMsgP = NULL;
    int err = sqlite3_exec( database, selectQ, ListDataCallback, (void*)myUserData, &selectErrMsgP );
    if( err ) {
        //handle error
    }
}

Had never had any leaks with this approach

Not the answer you're looking for? Browse other questions tagged or ask your own question.