何时调用 mysql_free_result (Resuing mysql_store_result, MYSQL_RES)

Posted

技术标签:

【中文标题】何时调用 mysql_free_result (Resuing mysql_store_result, MYSQL_RES)【英文标题】:when to call mysql_free_result (Resuing mysql_store_result, MYSQL_RES) 【发布时间】:2013-05-24 06:56:38 【问题描述】:

我有 2 个代码(程序)

计划 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);

其他代码”涉及一个 for 循环,该循环调用利用相同 res_set 存储来自 mysql_store_result 的结果的函数。 如图所示,我在 main 结束时只调用了一次 mysql_free_result(res_set);

valgrind 在上述情况下显示still reachable 内存问题(我选择忽略)。不存在其他泄漏。

计划 2:

类 mysqlClientClass 有以下私有变量,

MYSQL *connect;
MYSQL_RES *res_set; 
MYSQL_ROW row;

一些方法是(与我的问题相关),

mysqlClientClass::~mysqlClientClass()

if(connect!=NULL)
   
    mysql_free_result(res_set);
    mysql_close(connect);   


如果用户调用closeConnection失败,析构函数将关闭它(通过检查connect是否设置为NULL或否)

void mysqlClientClass::closeConnection()

    mysql_free_result(res_set);
    mysql_close(connect);
    connect = NULL;

getResults是整个代码中唯一使用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;
    

如果我没有在函数末尾释放res_set(并在析构函数/close Connection 中释放它)并且我多次调用这个函数 valgrind 报告,

=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)

这一切都归结为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)

根据mysql_store_result的manual页面

mysql_store_result() 将查询的整个结果读取到客户端, 分配一个 MYSQL_RES 结构,并将结果放入这个 结构。

它还建议我应该在使用后致电free_result

这似乎在程序 2 中按记录工作(当我不调用 mysql_free_result 时内存泄漏)但是为什么程序 1 没有显示任何泄漏?在程序 1 中,我也在各种函数之间多次调用 mysql_store_result,但每次都没有释放。

【问题讨论】:

【参考方案1】:

您不需要mysql_store_result 从查询中获取数据 - 使用带有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
    

这种方法从来没有任何泄漏

【讨论】:

以上是关于何时调用 mysql_free_result (Resuing mysql_store_result, MYSQL_RES)的主要内容,如果未能解决你的问题,请参考以下文章

使用 XmlSerializer.Deserialize 反序列化时何时调用类构造函数?

Node.js + Express + Redis,何时关闭连接?

何时使用缺失值与 NULL 值在 R 中传递未定义的函数参数,为啥?

applicationWillTerminate 何时调用,何时不调用

我应该何时调用 StateHasChanged 以及 Blazor 何时自动拦截某些更改?

R语言如何和何时使用glmnet岭回归