Valgrind(二) 几种内存泄露的情况

操作MySQL结果集后释放内存

代码中获取MySQL结果常用由mysql_store_result,结果用valgrind检查时发现了内存泄露问题:

由mysql_store_result()、mysql_use_result()、mysql_list_dbs()获得结果集,在完成对结果集的操作后,必须调用mysql_free_result()释放结果集使用的内存。每次查询返回的结果的地址是不一样的,所以每次都要释放,否则会造成内存泄露。

mysql_free_result 的危害太大,目前造成了很多问题,在将获取的SQL结果插入到容器时,出现了很多乱码和不正常的字符串.如果没有明显内存泄露,不再加这句命令.

mysql_init内存泄露

再次用valgrind检查操作MySQL的代码,发现还有一个泄露的情况:

一般在使用MySQL结束后,会调用mysql_close,但是这样解决不了这个泄露情况,应当调用mysql_library_end()释放 剩余的内存空间。所以MySQL的最后经常是:

1
2
3
mysql_free_result(result);
mysql_close(conn);
mysql_library_end();

如果是在类中使用MySQL,一般是把mysql_closemysql_library_end()放在析构函数里。

跨线程释放内存

我在类中使用了一个指针,打算在析构函数里释放其指向内存,编译运行都正常,但是用valgrind发现了问题:

内存地址在线程1的stack上,看代码发现这个指针的内存确实不是在主线程,所以不要在主线程上释放,否则提示free invalid

boost::thread创建的线程有内存泄露

比如这样创建线程:

1
2
3
4
5
6
7
8
9
10
void call()
{
cout<<"call"<<endl;
}

int main()
{
boost::thread thrd1(&call);
thrd1.join();
}

这种情况下不会有泄露,假如去掉join()一行,虽然还能正常运行,但就会有内存泄露

log4cpp::PropertyConfigurator::configure的内存泄露

ros::NodeHandle的内存泄露

在Kinetic的ros::NodeHandle源码里,一个指针没有delete就置为NULL,目前的melodic没有了这个bug,不必自己解决了。