0

我确实有一个代码结构,我从数据库中读取 Oracle 行,然后将其分配给一个表示其数据的通用模型(称为commonmodel::Model)。我在 Windows 7 上使用 VS2012。

我的问题是下面的这段代码,我在其中执行了一些语句,例如SELECT ...

我正在运行测试并且表是空的,所以没有数据从SELECT....from 数据库返回,因此里面的代码while (resultSet->next())没有被调用。

我的程序可以编译,但它在运行时返回数据 ( return retData) 时崩溃。我不知道是什么导致了这种行为,我想帮助解决它。

顺便说一句:我选择std::unique_ptr´s为 Oracle 创建指针,以便在不需要任何模式时让编译器释放这些指针。在那之后,我不需要在操作结束时删除它们。

std::vector<std::unique_ptr<commonmodel::Model>> OracleDatabase::ExecuteStmtReturningData(std::string sql, int& totalRecords, commonmodel::Model &modelTemplate)
{
    std::unique_ptr<oracle::occi::Statement> stmt(connection->createStatement());
    stmt->setAutoCommit(TRUE);
    std::unique_ptr<oracle::occi::ResultSet> res(stmt->executeQuery(sql));

    std::vector<std::unique_ptr<commonmodel::Model>> ret = getModelsFromResultSet(res, modelTemplate);

    return ret;
}

std::vector<std::unique_ptr<commonmodel::Model>> OracleDatabase::getModelsFromResultSet(std::unique_ptr<oracle::occi::ResultSet>& resultSet, commonmodel::Model &modelTemplate)
{
    std::vector<std::unique_ptr<commonmodel::Model>> retData;

    std::vector<oracle::occi::MetaData> resultMeta = resultSet->getColumnListMetaData();

    while (resultSet->next())
    {
         std::unique_ptr<commonmodel::Model> model = modelTemplate.clone();

         for (unsigned int i = 1; i <= resultMeta.size(); i++) // ResultSet starts with one, not zero
         {
             std::string label = resultMeta.at(i).getString(oracle::occi::MetaData::ATTR_NAME);
             setPropertyFromResultSet(resultSet, label, i, *model);
         }

         retData.push_back(std::move(model)); // unique_ptr can only be copied or moved.
     }


    return retData; <<<==== CRASH ON RETURN....
}
4

1 回答 1

3

您不能使用“库存”unique_ptr来处理 OCCI 对象和指针。OCCI 不希望您指向delete这些指针(这就是unique_ptr将要执行的操作),相反,他们希望您使用 OCCI 提供的机制来释放它们。

特别是,要释放Statement对象,您应该使用Connection::terminateStatement. ResultSet*和其他任何 OCCI 指针一样。

现在,您可以将自定义删除器提供给 unique_ptr 对象,但问题是您需要为此使用指向已经存在的“父”对象的指针 - 并且很难以这种方式管理独立指针的生命周期。

另一方面,我强烈建议不要使用 OCCI。这是一个非常糟糕的设计,没有正确记录的库。OCI 提供了更好的选择。

于 2016-04-14T21:18:12.090 回答