VS2012返回Oracle unique_ptr崩溃的向量

时间:2016-04-14 21:00:25

标签: c++ oracle visual-studio-2012 occi

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

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

我正在运行测试并且表是空的,因此数据库中没有从SELECT...返回任何数据,因此while (resultSet->next())内的代码段没有被调用。

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

BTW:我选择为Oracle指针创建std::unique_ptr´s,这样我就可以在不需要任何模式时让编译器释放这些指针。在那个wat中我不需要在操作结束时删除它们。

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....
}

1 个答案:

答案 0 :(得分:3)

您无法使用&#39; stock&#39; unique_ptr来处理OCCI对象和指针。 OCCI不希望你delete那些指针(这是unique_ptr将要做的事情),相反,他们希望你使用OCCI提供的机制释放它们。

特别是,要释放Statement个对象,您应该使用Connection::terminateStatement。对于此问题,ResultSet*和任何其他OCCI指针也是如此。

现在,您可以在unique_ptr对象中提供自定义删除工具,但问题是您需要使用指针已经存在的父亲&#39;对象 - 并且很难以这种方式管理独立指针的生命周期。

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