Valgrind检测内存泄漏
Detecting a memory leak with Valgrind
我正在用C++编写一个守护进程,它的任务很简单,就是将一些事件插入到mysql数据库中。
当我运行top命令时,我看到进程的内存需要增加,我认为我有内存泄漏,我开始使用Valgrind
我经营valgrind是这样的:
valgrind--tool=memcheck--leak check=yes--show reachable=yes--num个呼叫者=20——跟踪fds=是/my_app
我收到以下报告:
==17045== 128 bytes in 1 blocks are definitely lost in loss record 6 of 11
==17045== at 0x402A629: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==17045== by 0x40AAB63: my_thread_init (in /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0)
==17045== by 0x40AAE43: my_thread_global_init (in /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0)
==17045== by 0x40A92D7: my_init (in /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0)
==17045== by 0x40863FA: mysql_server_init (in /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0)
==17045== by 0x4087B28: mysql_init (in /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0)
==17045== by 0x8049890: write_db(std::string, std::string, std::string) (Listener.cpp:76)
==17045== by 0x804A692: SocketListener(void*) (Listener.cpp:182)
==17045== by 0x4052D4B: start_thread (pthread_create.c:308)
==17045== by 0x4582D3D: clone (clone.S:130)
函数write_db是这样的:
void write_db(std::string userid,std::string zona,std::string eveniment)
{
try
{
MYSQL * connect;
connect = mysql_init(NULL);
connect = mysql_real_connect(connect,"127.0.0.1","myusr","mypwd","mytbl",0,NULL,0);
std::string stmt = "INSERT INTO t_evenimente(placaid,codev,zona,cand) VALUES("" + userid + ""," + eveniment + ","" + zona + "",NOW())";
std::cout << stmt << std::endl;
mysql_query(connect,stmt.c_str());
mysql_close(connect);
std::cout << "Inserat eveniment obiectiv " << userid << std::endl;
}
catch (...)
{
std::cout <<"Exceptie MYSQL" << std::endl;
}
}
内存泄漏在哪里?我正在使用mysql_init,并按照文档中所说的关闭。。。可能是假阳性吗?
由于您只在函数内部使用connect
,因此不动态分配它更容易,并有内存泄漏的风险(很可能就是您看到的)。此外,MySQL API是一个C API,不会抛出任何异常供您捕获,这将简化您现在拥有的东西;
void write_db(std::string userid,std::string zona,std::string eveniment)
{
MYSQL connect;
mysql_init(&connect);
mysql_real_connect(&connect,"127.0.0.1","myusr","mypwd","mytbl",0,NULL,0);
std::string stmt = "INSERT INTO t_evenimente(placaid,codev,zona,cand) VALUES("" + userid + ""," + eveniment + ","" + zona + "",NOW())";
std::cout << stmt << std::endl;
mysql_query(&connect,stmt.c_str());
mysql_close(&connect);
std::cout << "Inserat eveniment obiectiv " << userid << std::endl;
}
当然,这仍然忽略了错误处理,您需要将其添加回来。
mysql_init返回一个堆分配的对象,该对象需要由mysql_close释放。当mysql_init和mysql_close之间的某个东西抛出异常时,您永远不会调用close。快速修复-将mysql_close添加到catch块中。更好的修复-了解/使用RAII。
正如Angew所指出的,当您调用mysql_real_connect时,实际上很可能会泄漏连接(除非您在日志中看到异常文本)。你也可以使用RAII来避免这种情况。
相关文章:
- C++功能泄漏内存,我是C++新手,不确定如何解决
- 我的堆栈弹出式磁带的实现是否泄漏内存?
- 将 c++ 向量转换为字符 ** 而不会泄漏内存
- 析构函数 C++ 使泄漏内存
- 构造函数对象赋值是否泄漏内存
- corba :: orb_init泄漏内存
- Gmock泄漏内存
- 如何在不泄漏内存的情况下删除链接列表
- Visual C ODBC关闭记录集泄漏内存
- 为什么泄漏内存比在动态数组上执行 delete[] 慢
- OpenGL正在泄漏内存.哪个对象未释放
- 可以std ::退出泄漏内存
- uiautomation findall泄漏内存
- 为什么在此OpenCL代码中泄漏内存,为什么要泄漏内存
- pthread在完成后会泄漏内存
- win32 标准::线程泄漏内存
- 返回指向同一变量的指针是否会泄漏内存
- 使用clectType(new any_type())可能会泄漏内存泄漏
- Windows开发:如何确定我的应用程序是否正在泄漏内存
- WinHttp打开泄漏内存