我正在开发一个应该可以运行几天的 C ++ 程序,所以它的内存消耗似乎增长得非常快,这有点麻烦。
程序的完整代码有点长,所以我会发布相关的东西。结构如下:
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();
}
}
上面初始化的计时器功能如下:
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();
}
所以基本上,因为我没有在Web界面中设置修改MyStatus选项卡的起始位,所以程序每秒调用 readmysql 函数两次(计时器的间隔)。 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;
}
我认为这个函数中的变量存储在堆栈中,并在离开函数时自动释放。然而,似乎内存的某些部分没有被释放,因为它毕竟只是增长。如您所见,我尝试在两个变量上使用delete函数。似乎没有效果。我在内存管理等方面做错了什么?
感谢您的帮助!
问候奥利弗。
答案 0 :(得分:3)
至少mysql_store_result正在泄漏。来自documentation:
在调用mysql_query()或mysql_real_query()之后,必须为每个成功生成结果集的语句(SELECT,SHOW,DESCRIBE,EXPLAIN,CHECK TABLE等)调用mysql_store_result()或mysql_use_result()。 完成结果集后,您还必须调用mysql_free_result()。
答案 1 :(得分:0)
如果你的程序不断消耗内存(没有释放它),那么你有一个内存泄漏。
检测内存泄漏的一种好方法是通过内存调试器运行它,例如, valgrind
:
$ valgrind /path/to/my/program
一旦你的程序开始吃内存,就停止它,valgrind会给你一个很好的总结,说明你的程序在哪里分配了从未被释放的内存。
没有必要让系统耗尽内存并崩溃;等到它吃掉了一些尚未释放的内存。然后修复你的代码。然后重复,直到不再能检测到内存错误。
另请注意,valgrind会拦截您的系统内存管理。这通常会导致(严重)性能损失。