2016-07-13 14 views
0

私はC++のプログラムを数日間実行する必要があるので、少し面倒ですそのメモリ消費量は非常に速くなっているようです。C++プログラムのメモリ使用量が増えて(Debianの「トップ」に表示される)、クラッシュするまで

プログラムの完全なコードは少し長いので、私は関連するものを投稿します。構造は以下の通りです:

void catch_alarm (int sig) 
{ 
//Set the statemachine to state 1 (reading in new values) 

    start = readmysql("MyStatus", "Start", 0); 
    stop = readmysql("MyStatus", "Stop", 0); 

     if (start == 1){ 
      state = 1; 
     } 
     if (stop == 1){ 
      state = 5; 
     } 


    //printf("Alarm event\n"); 
    signal (sig, catch_alarm); 

    return void(); 
} 

をので、基本的に、私はMyStatusを変更するウェブインターフェースで開始ビットを設定していないよ以来:

int main (void){ 
//initialization of the global variables 
error = 0; 
state = 0; 
cycle = 0; 
exportcycle = 0; 
status = 0; 
counter_temp_ctrl = 0; 
start = 0; 
stop = 0; 


inittimer(); 
mysql_del ("TempMeas"); 
mysql_del ("TempMeasHist"); 
mysql_del ("MyControl"); 
mysql_del ("MyStatus"); 
initmysql(); 



while(1){ 

    statemachine(); 

    pause(); 

    } 

} 

上記初期化されているタイマー機能は以下のとおりです。このプログラムは、readmysql関数を1秒に2回(タイマーの間隔)呼び出すだけです。 readmysql機能は以下の通りである:

float readmysql(string table, string row, int lastvalue){ 
float readdata = 0; 

// Initialize a connection to MySQL 
MYSQL_RES *mysql_res; 
MYSQL_ROW mysqlrow; 
MYSQL *con = mysql_init(NULL); 
if(con == NULL) 
{ 
error_exit(con); 
} 


if (mysql_real_connect(con, "localhost", "user1", "user1", "TempDB", 0, NULL, 0) == NULL) 
{ 
error_exit(con); 
} 

if (lastvalue == 1){ 
    string qu = "Select "+ row +" from "+ table +" AS a where MeasTime=(select MAX(MeasTime) from "+ table; 
    error = mysql_query(con, qu.c_str()); 
} 
else{ 
    string qu = "Select "+ row +" from "+ table; 
    error = mysql_query(con, qu.c_str()); 
} 


mysql_res = mysql_store_result(con); 

while((mysqlrow = mysql_fetch_row(mysql_res)) != NULL) 
{ 
    readdata = atoi(mysqlrow[0]); 
} 

//cout << "readdata "+table+ " "+row+" = " << readdata << endl; 

// Close the MySQL connection 
mysql_close(con); 

//delete mysql_res; 
//delete mysqlrow; 


return readdata; 
} 

私は、この関数内の変数がスタックに格納されており、機能を離れるときautomaticaly解放されると思いました。しかし、記憶の一部は解放されていないように見えます。ご覧のとおり、2つの変数に対してdelete関数を使用しようとしました。効果がないと思われる。メモリ管理の面で何が間違っていますか?

ありがとうございました!

お挨拶オリバー。

+0

何らかの理由でメモリがリークしています。また、 '!= NULL'は必要ありません。 – tadman

+0

漏れがなくなるまで疑わしい行を削除してください。 –

+0

私は比較的最近、VBAでの長期滞在の後にC++のスキルをリハーサルし始めましたが、C#ではもっと最近のものがありましたので、間違っていると推測されるかもしれませんが、 'error_exit()'と ' mysql_close() '接続インスタンスによって使用されるメモリを解放します。 – Uueerdo

答えて

3

少なくとも、mysql_store_resultがリークしています。 documentationから:

するmysql_query()またはmysql_real_query()を呼び出した後、あなたは、SELECTは、SHOW、CHECK TABLEを、DESCRIBE EXPLAIN(成功し、結果セットを生成し、すべての文のためにmysql_store_result()またはmysql_use_result()を呼び出す必要がありますなど)。 結果セットの終了後にmysql_free_result()を呼び出す必要があります。

+0

ありがとうございます!それは非常に有用だった。私は明日これをテストするつもりですが、それは少なくとも1つの問題であるようです。 – Bardai

0

あなたのプログラムが継続的に(今までそれを解放せず)のメモリを消費した場合は、メモリリークを持っています。

メモリリークを検出するには、メモリデバッガなどで実行してください。 valgrind

$ valgrind /path/to/my/program 

あなたのプログラムがメモリを食べ始めたら、それを停止し、valgrindのは、あなたのプログラムが解放されていませんでしたメモリを割り当てられた場所についての素敵な要約を提供します。

システムにメモリが不足してクラッシュする必要はありません。 メモリが解放されていないまで待ってください。次にコードを修正します。その後、メモリエラーが検出されなくなるまで繰り返します。

また、valgrindはシステムのメモリ管理を妨害します。これにより、通常、(重大度)のパフォーマンスが低下します。

関連する問題