首页 > 解决方案 > C++ MySql 连接器 - 查询超出范围的结果

问题描述

我遇到了 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 %i\n", __FILE__, __LINE__ );
       return false;
   }
   else
   {
        printf("Result is not null File: %s Line %i\n", __FILE__, __LINE__ );
   }

   return true;
}

如果我有一个foo使用正确参数调用上述函数的函数。printf将打印结果不是 null的声明,但是在foo执行之后ExecuteQuery,传递给函数的指针变为NULL

标签: c++mysql-connector

解决方案


有几个问题:

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 在删除ResultSet时释放Statement

就像@nos 指出的那样,当您调用时delete statement,您还释放了保存您的信息的资源result

result仍然会有一个有效的值,因为它不会知道释放的内存,但是如果你访问它,它可能会导致分段错误。

处理此问题的正确方法是:

  • 复制结果
  • 或者
  • 让调用者也传递一个语句对象,并在使用结果中的值后释放它。

推荐阅读