C++MySql连接器-查询的结果超出范围
C++ MySql Connector - results from query going out of scope
我在执行C++mysql连接器查询的结果时遇到了作用域问题。
在下面的代码中,ResultSet *
结果是从另一个函数传递的,最初是NULL
;然而,在执行线result = statement->executeQuery( query )
之后,结果不再是NULL
。
表中也没有打印错误。
从该函数返回时会出现问题。ResultSet *
的结果从不是NULL
变为等于NULL
。
显然,sql查询结果存在某种形式的作用域。也许他们的函数正在返回对局部变量的引用(真的不确定)?
我该如何绕过这个作用域问题,以便调用该函数的类/函数可以随心所欲地处理结果,并减轻在该包装器中编写一堆专用函数的需要?此外,应尽量减少副本,因此应使用指针。
bool MySQLConnector::ExecuteQuery( std::string query, sql::ResultSet * result )
{
//connection is a member variable and has been initialized
sql::Statement * statement = connection->createStatement();
try
{
result = statement->executeQuery( query );
}
catch( sql::SQLException &e )
{
//handle errors
}
delete statement;
if( result == NULL )
{
printf( "Result is null File: %s Line %in", __FILE__, __LINE__ );
return false;
}
else
{
printf("Result is not null File: %s Line %in", __FILE__, __LINE__ );
}
return true;
}
如果我有一个函数foo
,它用正确的参数调用上面的函数。声明结果不为空的printf
将打印出来,但在foo
中,在执行ExecuteQuery
之后,传递到函数中的指针将变为NULL
。
有几个问题:
1.result
通过值
通过值传递result
。这意味着函数在调用方法时会接收到您传递的指针的副本。
例如,如果调用ExecuteQuery
的代码如下所示:
std::string query("SELECT ...");
sql::ResultSet *result = NULL;
ExecuteQuery(query, result);
那么ExecuteQuery
不能改变result
的值,因为它被复制到方法中。若要更改其值,则应传递对结果的引用。您可以将ExecuteQuery
更改为:
bool MySQLConnector::ExecuteQuery( std::string query, sql::ResultSet *& result )
然后,ExecuteQuery
操作原始指针,而不是副本。
2.MySQL C++API在删除Statement
时释放ResultSet
正如@nos所指出的,当你调用delete statement
时,你也释放了为你的result
保存信息的资源。
result
仍然有一个有效的值,因为它不会知道释放的内存,但如果您访问它,它可能会导致分段错误。
正确的处理方法是:
- 复制结果
- 或
- 让调用者也传递一个语句对象,并在使用result中的值后释放它
bool MySQLConnector::ExecuteQuery( std::string query, sql::ResultSet * result )
^^^^^^^^
这里,result很像函数中的局部变量,它包含调用方变量的副本。
当您在ExecuteQuery中为其赋值时,它只会影响函数中的变量,而不会影响调用方的变量。
您可以将其作为引用,这样它就会引用调用方的变量,如下所示:
bool MySQLConnector::ExecuteQuery( std::string query, sql::ResultSet *&result )
另一种方法是传递一个指向变量的指针(由于变量本身就是一个指针,因此您将处理一个指向指针的指针)。这样还可以修改调用者的指针:
bool MySQLConnector::ExecuteQuery( std::string query, sql::ResultSet **result ) {
...
*result = statement->executeQuery( query );
这也需要对调用者进行修改,因此它会传递一个指向其本地变量的指针,例如
sql::ResultSet *rs;
c->ExecuteQuery("select ...", &rs);
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- valgrind-hellgrind与泄漏检查的结果不同
- 尝试通过多个向量访问变量时,向量下标超出范围
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 在基于范围的for循环中使用结构化绑定声明
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在运行时使用范围更新结果
- 当在另一个范围中,将SelfAdjointeigensolver保存为成员的结果被重新引入
- 为什么在C 中不确定,为签名类型的对象分配范围的值的结果
- C++MySql连接器-查询的结果超出范围
- 代码覆盖范围结果:导出到Excel
- 如何使用boost::any_range连接多个boost范围并作为函数w/o的结果返回
- C++ vector.end() 给出超出范围的结果 - 请告知