C++ mysqlcppconn程序内存泄漏
我有一个运行的程序占用越来越多的内存。这种情况一直持续到整个程序崩溃。我已经把它缩小到这一部分--如果我把它注释掉,所使用的内存就不会再增加了 为什么这段代码给了我内存泄漏?指针是否因某种原因未被删除?我是否使用了错误的C++ mysqlcppconn程序内存泄漏,c++,mysql,C++,Mysql,我有一个运行的程序占用越来越多的内存。这种情况一直持续到整个程序崩溃。我已经把它缩小到这一部分--如果我把它注释掉,所使用的内存就不会再增加了 为什么这段代码给了我内存泄漏?指针是否因某种原因未被删除?我是否使用了错误的executeUpdate函数 #include <cppconn/prepared_statement.h> // preparedStatement sql::PreparedStatement* pstatement; try{ for(const auto&
executeUpdate
函数
#include <cppconn/prepared_statement.h> // preparedStatement
sql::PreparedStatement* pstatement;
try{
for(const auto& bar : m_bars) {
std::string sql = "INSERT INTO "
+ m_table_name
+ " VALUES (' "
+ trade_platform::datetime::toString(datetime) + "', '"
+ bar.first + "', "
+ "'IB', "
+ std::to_string(bar.second.getOpen()) + ", "
+ std::to_string(bar.second.getHigh()) + ", "
+ std::to_string(bar.second.getLow()) + ", "
+ std::to_string(bar.second.getClose()) + ", "
+ std::to_string(bar.second.getVolume()) + ");";
pstatement = m_conn->prepareStatement(sql);
// prepare our statement and execute query
pstatement->executeUpdate();
}
}catch(const std::exception& e){
std::cerr << "flushToDB problem: " << e.what() << "\n";
}catch(...){
std::cerr << "unspecified flushToDB problem\n";
}
// free
delete pstatement;
\include//preparedStatement
sql::PreparedStatement*pstatement;
试一试{
用于(常量自动和条形:m_条形){
std::string sql=“插入到”
+m_表_名称
+“值('”
+交易平台::datetime::toString(datetime)+“,”
+bar.first+“,”
+“‘IB’,”
+std::to_字符串(bar.second.getOpen())+“,”
+std::to_字符串(bar.second.getHigh())+“,”
+std::to_字符串(bar.second.getLow())+“,”
+std::to_字符串(bar.second.getClose())+“,”
+std::to_字符串(bar.second.getVolume())+“”;”;
pstatement=m_conn->prepareStatement(sql);
//准备语句并执行查询
pstatement->executeUpdate();
}
}捕获(const std::exception&e){
std::cerr您正在创建sql语句N
次,但只有最后一条被删除
删除每条语句会更好:
#include <memory>
...
try{
for(const auto& bar : m_bars) {
std::string sql = "INSERT INTO "
+ m_table_name
+ " VALUES (' "
+ trade_platform::datetime::toString(datetime) + "', '"
+ bar.first + "', "
+ "'IB', "
+ std::to_string(bar.second.getOpen()) + ", "
+ std::to_string(bar.second.getHigh()) + ", "
+ std::to_string(bar.second.getLow()) + ", "
+ std::to_string(bar.second.getClose()) + ", "
+ std::to_string(bar.second.getVolume()) + ");";
std::unique_ptr<sql::PreparedStatement> pstatement(m_conn->prepareStatement(sql)); // enabling RAII
// prepare our statement and execute query
pstatement->executeUpdate();
// unique_ptr wil automatically call delete on sql statement
// after pstatement leaves the scope, and c++ guarantees that
// the destructor of pstatement will be called always even in case of exception thrown
}
}catch(const std::exception& e){
std::cerr << "flushToDB problem: " << e.what() << "\n";
}catch(...){
std::cerr << "unspecified flushToDB problem\n";
}
#包括
...
试一试{
用于(常量自动和条形:m_条形){
std::string sql=“插入到”
+m_表_名称
+“值('”
+交易平台::datetime::toString(datetime)+“,”
+bar.first+“,”
+“‘IB’,”
+std::to_字符串(bar.second.getOpen())+“,”
+std::to_字符串(bar.second.getHigh())+“,”
+std::to_字符串(bar.second.getLow())+“,”
+std::to_字符串(bar.second.getClose())+“,”
+std::to_字符串(bar.second.getVolume())+“”;”;
std::unique_ptr pstatement(m_conn->prepareStatement(sql));//启用RAII
//准备语句并执行查询
pstatement->executeUpdate();
//unique_ptr将自动调用sql语句上的delete
//在p声明离开范围后,C++保证
//即使抛出异常,也将始终调用pstatement的析构函数
}
}捕获(const std::exception&e){
std::cerr您正在创建sql语句N
次,但只有最后一条被删除
删除每条语句会更好:
#include <memory>
...
try{
for(const auto& bar : m_bars) {
std::string sql = "INSERT INTO "
+ m_table_name
+ " VALUES (' "
+ trade_platform::datetime::toString(datetime) + "', '"
+ bar.first + "', "
+ "'IB', "
+ std::to_string(bar.second.getOpen()) + ", "
+ std::to_string(bar.second.getHigh()) + ", "
+ std::to_string(bar.second.getLow()) + ", "
+ std::to_string(bar.second.getClose()) + ", "
+ std::to_string(bar.second.getVolume()) + ");";
std::unique_ptr<sql::PreparedStatement> pstatement(m_conn->prepareStatement(sql)); // enabling RAII
// prepare our statement and execute query
pstatement->executeUpdate();
// unique_ptr wil automatically call delete on sql statement
// after pstatement leaves the scope, and c++ guarantees that
// the destructor of pstatement will be called always even in case of exception thrown
}
}catch(const std::exception& e){
std::cerr << "flushToDB problem: " << e.what() << "\n";
}catch(...){
std::cerr << "unspecified flushToDB problem\n";
}
#包括
...
试一试{
用于(常量自动和条形:m_条形){
std::string sql=“插入到”
+m_表_名称
+“值('”
+交易平台::datetime::toString(datetime)+“,”
+bar.first+“,”
+“‘IB’,”
+std::to_字符串(bar.second.getOpen())+“,”
+std::to_字符串(bar.second.getHigh())+“,”
+std::to_字符串(bar.second.getLow())+“,”
+std::to_字符串(bar.second.getClose())+“,”
+std::to_字符串(bar.second.getVolume())+“”;”;
std::unique_ptr pstatement(m_conn->prepareStatement(sql));//启用RAII
//准备语句并执行查询
pstatement->executeUpdate();
//unique_ptr将自动调用sql语句上的delete
//在p声明离开范围后,C++保证
//即使抛出异常,也将始终调用pstatement的析构函数
}
}捕获(const std::exception&e){
这就是它,如果你看一下文件()语句更改后,它们会删除指针并分配一个新指针。请注意,如果使用实际准备的语句,它们不会删除指针,在这种情况下,它们只是使用不同的值执行指针。最好使用RAII
来处理delete
,然后必须管理每种情况,否则可能会引发异常。@PaulMcKenzie,这是绝对正确的,我已经用RAII@Renat谢谢!顺便说一句,赋值运算符对我不起作用,所以我最终使用了构造函数,即std::unique\u ptr p\pstmnt(m\u conn->prepareStatement(sql))
顺便说一句,在早期版本中对nullptr
的检查是多余的。delete nullptr
什么都不做(安全)。不安全的是,指针在声明上没有初始化为null。如果查看文档()语句更改后,它们会删除指针并分配一个新指针。请注意,如果使用实际准备的语句,它们不会删除指针,在这种情况下,它们只是使用不同的值执行指针。最好使用RAII
来处理delete
,然后必须管理每种情况,否则可能会引发异常。@PaulMcKenzie,这是绝对正确的,我已经用RAII@Renat谢谢!顺便说一句,赋值运算符对我不起作用,所以我最终使用了构造函数,即std::unique\u ptr p\pstmnt(m\u conn->prepareStatement(sql))
btw在早期版本中检查nullptr
是多余的。delete nullptr
不起任何作用(安全)。不安全的是,指针在Declaration上没有初始化为null。只是为了以防万一,您目前没有使用准备好的语句,您的代码仍然可以接受SQL注入。@FMashiro是的,谢谢,我昨晚意识到了这一区别。幸运的是,此应用程序正在一台专用服务器上运行,以防您需要ren不知道,您当前没有使用准备好的语句,您的代码仍然可以接受SQL注入。@FMashiro是的,谢谢,我昨晚意识到了这一区别。幸运的是,这个应用程序正在一个私有服务器上运行