我确实有一个代码结构,可以从数据库中读取Oracle行,然后将其分配给代表其数据的通用模型(称为commonmodel::Model
)。我在Windows 7上使用VS2012。
我的问题是下面的这段代码,我在其中执行某些语句,例如SELECT ...
我正在运行测试,并且表为空,因此没有SELECT...
.data从数据库返回任何数据,因此不会调用while (resultSet->next())
中的这段代码。
我的程序已编译,但在运行时由于返回数据(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....
}
最佳答案
您不能使用'stock'unique_ptr
处理OCCI对象和指针。 OCCI不想让您delete
这些指针(这是unique_ptr
要做的),相反,他们希望您使用OCCI提供的机制来释放它们。
特别是,要释放Statement
对象,应使用Connection::terminateStatement
。与ResultSet*
相同,与此有关的所有其他OCCI指针也是如此。
现在,您可以将自定义删除器提供给unique_ptr对象,但问题是您需要为此使用指向已存在的“父”对象的指针-很难以这种方式管理独立指针的生存期。
另外,我强烈建议您不要使用OCCI。这是一个设计不良,没有正确记录的库。 OCI提供了更好的选择。
关于c++ - VS2012 Oracle unique_ptr崩溃的返回 vector ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36633904/