2016-04-14 85 views
0

我确实有一个代码结构,我从数据库中读取Oracle行,然后将其分配给代表其数据的公共模型(称为commonmodel::Model)。 I'm使用Windows 7VS2012 Oracle unique_ptr崩溃的返回向量

我的问题是这段代码的下方,在那里我做执行一些语句像SELECT ...

I'm运行试验和表是空的,所以没有数据VS2012从SELECT... .from数据库返回,因此while (resultSet->next())中的代码片段未被调用。

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

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

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

回答

3

您不能使用'stock'unique_ptr来处理OCCI对象和指针。 OCCI不希望你给delete这些指针(这是unique_ptr要做的),相反,他们希望你使用OCCI提供的机制释放它们。

特别是,要免费Statement对象,你应该使用Connection::terminateStatement。对于ResultSet*以及任何其他OCCI指针,这一点相同。

现在,您可以将定制删除器提供到unique_ptr对象中,但问题是您需要使用指向已存在的“父”对象的指针 - 并且很难管理独立指针的生存期这样的方式。

在旁注中,我强烈建议使用OCCI的针对。这是一个非常糟糕的设计,没有妥善记录的图书馆。 OCI提供了一个更好的选择。

+0

是的。通过OCCI,您可以轻松地解决ABI稳定性问题。 Oracle不会重新编译它,只是因为它不再工作。对于纯OCI,使用任何开源包装更安全。 – ibre5041