VS2012 Oracle unique_ptr 崩溃的返回向量
VS2012 Returning vector of Oracle unique_ptr´s crash
我有一个代码结构,我从数据库中读取 Oracle 行,然后分配给一个代表其数据的通用模型(称为 commonmodel::Model
)。我在 Windows 7.
上使用 VS2012
我的问题是下面这段代码,我在其中执行了一些语句,例如 SELECT ...
我正在 运行 进行测试并且表是空的,所以没有数据从 SELECT...
. 从数据库返回,因此 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 对象提供自定义删除器,但问题是您需要为此使用指向现有 'parent' 对象的指针 - 这很难以这种方式管理独立指针的生命周期。
附带说明一下,我强烈建议反对 使用 OCCI。这是一个设计非常糟糕,没有正确记录的库。 OCI 提供了更好的选择。
我有一个代码结构,我从数据库中读取 Oracle 行,然后分配给一个代表其数据的通用模型(称为 commonmodel::Model
)。我在 Windows 7.
我的问题是下面这段代码,我在其中执行了一些语句,例如 SELECT ...
我正在 运行 进行测试并且表是空的,所以没有数据从 SELECT...
. 从数据库返回,因此 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 对象提供自定义删除器,但问题是您需要为此使用指向现有 'parent' 对象的指针 - 这很难以这种方式管理独立指针的生命周期。
附带说明一下,我强烈建议反对 使用 OCCI。这是一个设计非常糟糕,没有正确记录的库。 OCI 提供了更好的选择。