11

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

その他のコードres_set」には、からの結果を格納するために同じものを利用する関数を呼び出す for ループが含まれますmysql_store_resultmysql_free_result(res_set);ご覧のとおり、メインの最後に 1 回だけ呼び出します。

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

mysql_store_result() は、クエリの結果全体をクライアントに読み取り 、MYSQL_RES 構造を割り当て、結果をこの構造に配置します。

また、使用後に電話する必要があることも示唆していfree_resultます。

これは、プログラム 2 で文書化されているように動作するようです ( を呼び出さないとメモリ リークが発生しますmysql_free_result) が、プログラム 1 でリークが発生しないのはなぜですか? プログラム 1 でも、mysql_store_result毎回解放せずに、さまざまな関数の間でいくつかの呼び出しを行います。

4

1 に答える 1