C++ MySQL C+中的内存泄漏+;连接器
我使用MySQL C++连接器。Valgrind显示它在每个连接上都泄漏了192字节。 它只在线程化环境中泄漏内存,没有线程化。它没有泄漏任何内存。我做错了什么?我需要调用一些其他函数来进行清理吗? 示例代码:C++ MySQL C+中的内存泄漏+;连接器,c++,mysql,mysql-connector,C++,Mysql,Mysql Connector,我使用MySQL C++连接器。Valgrind显示它在每个连接上都泄漏了192字节。 它只在线程化环境中泄漏内存,没有线程化。它没有泄漏任何内存。我做错了什么?我需要调用一些其他函数来进行清理吗? 示例代码: #include <pthread.h> #include <iostream> #include <cppconn/driver.h> #include <cppconn/exception.h> #include <cppconn
#include <pthread.h>
#include <iostream>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
using namespace std;
void* test(void* arg) {
try {
sql::Driver *driver;
sql::Connection *con;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "root");
/* Connect to the MySQL test database */
con->setSchema("test");
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
return NULL;
}
int main() {
pthread_t thread1, thread2, thread3, thread4;
pthread_create(&thread1, NULL, test, NULL);
pthread_create(&thread2, NULL, test, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
无效*测试(无效*参数){
试一试{
sql::Driver*驱动程序;
连接*con;
/*创建连接*/
driver=get_driver_instance();
con=驱动程序->连接(“tcp://127.0.0.1:3306“,”根“,”根“);
/*连接到MySQL测试数据库*/
con->setSchema(“测试”);
删除con;
}捕获(sql::SQLException&e){
正如WhozCraig建议的那样,您可以在测试函数中添加delete Driver;
,但我建议对MYSQL的所有内容使用auto\u ptr
或C++11unique\u ptr
或shared\u ptr
,您永远不必担心内存泄漏
以此为例,
使用C++11
std::unique_ptr< sql::Connection > con( driver->connect("tcp://127.0.0.1:3306", "root", "root"));
这可能是你需要的
还有一个可能非常有用的方法,它与您的做法有点不同。第一个问题是您的代码是错误的。try
块中出现任何异常时,程序将永远不会到达delete con;
语句,您将与MySQL服务器保持打开的连接,并出现内存泄漏。您必须声明并删除eletecon
在try
之外阻止或使用C++11智能指针:
错误:
try {
sql::Connection *con = driver->connect("URL", "user", "password");
// code
delete con;
}
catch (const sql::SQLException &e) {
// code
}
正确,在C++11之前:
sql::Connection *con = NULL;
try {
con = driver->connect("URL", "user", "password");
// code
}
catch (const sql::SQLException &e) {
// code
}
delete con; // delete on NULL is harmless.
con = NULL;
try {
// unique_ptr will automatically call delete when it goes out of scope.
// That will also happen in case of exception.
std::unique_ptr<sql::Connection> con (driver->connect("URL", "user", "password"));
// code
}
catch (const sql::SQLException &e) {
// code
}
正确,C++11,推荐方式:
sql::Connection *con = NULL;
try {
con = driver->connect("URL", "user", "password");
// code
}
catch (const sql::SQLException &e) {
// code
}
delete con; // delete on NULL is harmless.
con = NULL;
try {
// unique_ptr will automatically call delete when it goes out of scope.
// That will also happen in case of exception.
std::unique_ptr<sql::Connection> con (driver->connect("URL", "user", "password"));
// code
}
catch (const sql::SQLException &e) {
// code
}
试试看{
//unique_ptr在超出范围时将自动调用delete。
//在例外情况下也会发生这种情况。
std::unique_ptr con(驱动程序->连接(“URL”、“用户”、“密码”);
//代码
}
catch(constsql::SQLException&e){
//代码
}
另外,driver=get\u driver\u instance();
应该在程序中只调用一次,而不是在每个线程中。因此,应该将sql::driver*driver;
设置为全局变量,并在main()中调用driver=get\u driver\u instance();
在创建任何线程之前。由于不了解mysql,valgrind与您的代码相关的转储表明泄漏是驱动程序实例,但这有可能被隐藏在TLS中并用于缓存。我很想看看循环中的代码会发生什么(即每个线程调用10次)这对你来说是微不足道的。@WhozCraig如何释放驱动程序的内存。它的析构函数是私有的?@VivekGoel我面临着同样的问题。你能提供详细的解决方法吗?除此之外,每当try…catch块发生异常时,你的程序就会泄漏,驱动程序
使用错误。你需要有一个glo用于驱动程序的bal变量,只从main()
调用一次get\u driver\u instance()
。不要在driver
上调用delete,也不要尝试以某种方式释放它,它是一个嵌入式结构,应该一直存在到程序退出为止。使用线程时,在每个新线程中都必须调用driver->threadInit()
。线程使用完MySQL后,在线程终止之前,必须调用驱动程序->线程结束();
。如果我试图删除驱动器对象,则会出现以下错误。虚拟sql::驱动程序::~driver()'是否受保护?我做了一些挖掘,我们在生产中使用了此功能。我们的代码中没有delete driver
,但在文档和代码中有一个con->close();
beforedelete con
如果你只是为驱动程序添加解构器,它就解决了问题。我面临同样的问题,但无法得到你提供的解决方案。如何为驱动程序添加解构器有点让人困惑?你的意思是从驱动程序派生另一个类还是其他方法?
try {
// unique_ptr will automatically call delete when it goes out of scope.
// That will also happen in case of exception.
std::unique_ptr<sql::Connection> con (driver->connect("URL", "user", "password"));
// code
}
catch (const sql::SQLException &e) {
// code
}