【问题标题】:"Access violation" Error on displaying string of simple Oracle Query (VS10 Exp C++)显示简单 Oracle 查询字符串时出现“访问冲突”错误(VS10 Exp C++)
【发布时间】:2013-01-30 21:13:12
【问题描述】:

我正在努力解决有关使用 occi 通过 C++ 向 Oracle 数据库运行 SQL 语句的问题。我的代码如下:

#include <iostream>
#include "occi.h"

namespace oc = oracle::occi;

int main() {
    std::cout << "Setting up environment...\n";
    oc::Environment * env = oc::Environment::createEnvironment();

    std::cout << "Setting up connection...\n";
    oc::Connection * conn = env->createConnection("user","pass","server");

    std::cout << "Creating statement...\n";
    //Very simply query... 
    oc::Statement * stmt = conn->createStatement("SELECT '1' FROM dual");

    std::cout << "Executing query...\n";
    oc::ResultSet * rs = stmt->executeQuery();

    while(rs->next()) {
            std::cout << rs->getString(1) << std::endl; //Error is thrown at this line, but after printing since I can see '1' on the console.
    }


    stmt->closeResultSet(rs);
    conn->terminateStatement(stmt);
    env->terminateConnection(conn);
    oc::Environment::terminateEnvironment(env);

    return 0;
}

显示的错误是:

MyDatabaseApp.exe 中 0x1048ad7a (msvcp100d.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0xccccccd0。

我的程序在以下代码行的“xstring”内停止:

    #if _ITERATOR_DEBUG_LEVEL == 0

    ....

    #else /* _ITERATOR_DEBUG_LEVEL == 0 */
    typedef typename _Alloc::template rebind<_Elem>::other _Alty;

    _String_val(_Alty _Al = _Alty())
            : _Alval(_Al)
            {   // construct allocator from _Al
            ....
            }

    ~_String_val()
            {   // destroy the object
            typename _Alloc::template rebind<_Container_proxy>::other
                    _Alproxy(_Alval);  

            this->_Orphan_all(); //<----------------------Code stops here

            _Dest_val(_Alproxy, this->_Myproxy);
            _Alproxy.deallocate(this->_Myproxy, 1);
            this->_Myproxy = 0;
            }
    #endif /* _ITERATOR_DEBUG_LEVEL == 0 */

如果我将查询更改为:

oc::Statement * stmt = conn->createStatement("SELECT 1 FROM dual"); 

和循环语句:

std::cout << rs->getInt(1) << std::endl;

它工作正常,没有错误。我认为这是因为获取一个整数只是返回一个原语,但是当一个对象被返回时它会爆炸(我认为是析构函数,但我不确定为什么......)

我今天已经玩了好几个小时了,但我被卡住了。

关于我的系统的一些信息:

  • 操作系统 - Windows XP
  • Oracle 版本 - 10g
  • IDE - Microsoft Visual Studio 2010 Express C++

我的项目属性如下:

  • C/C++ - 常规 - 附加包含目录 = C:\oracle\product\10.2.0\client_1\oci\include;%(AdditionalIncludeDirectories)
  • C/C++ - 代码生成 - 多线程调试 DLL (/MDd)
  • 链接器 - 常规 - 附加库目录 = C:\oracle\product\10.2.0\client_1\oci\lib\msvc\vc8;%(AdditionalLibraryDirectories)
  • 已链接 - 输入 - 附加依赖项 = oraocci10.lib;oraocci10d.lib;%(AdditionalDependencies)

我希望我没有对太多信息感到困惑...任何帮助或见解都会很棒,在此先感谢!

EDIT 如果我重写循环,将值存储在局部变量中,则会在循环结束时抛出错误:

while(rs->next()) {
    std::string s = rs->getString(1); //s is equal to "1" as expected
    std::cout << s << std::endl; //This is executed successfully
} //Error is thrown here

【问题讨论】:

  • 如果将 rs->getString(1) 分配给本地字符串变量以在调试器中检查它会怎样?这说明了什么?
  • @LeorA 这是我的第一个想法。因此,如果我创建一个局部变量并将其值分配给 'rs->getString(1)',它的值是“1”(如预期的那样)并且它会打印出来,但我在关闭“}”时得到相同的错误循环...
  • 看起来像是某种内存损坏问题。祝你好运。

标签: c++ oracle database-connection resultset occi


【解决方案1】:

此类问题通常来自最终用户和提供者的构建环境 (IDE) 的差异。

检查this

相关问题:

首先尝试使用正确的 lib 和 dll。如果在调试模式下编译,那么所有的库和 dll 都必须是调试的。使用 VC++ Modules 视图确保加载了正确的 DLL。

我很幸运,我的应用程序为 MSVC2010 编译了所有库。所以我只是检查调试和发布模式的 DLL 并得到工作的应用程序。

【讨论】:

  • 感谢您的链接,大约一个月前我重新访问了这个问题,我发现 MSVC2010 库仅用于 oracle 11g。我们运行的是 10g,所以我已经安装了 MSVC2005 并加载了适当的调试库,并且它工作了(发布模式库由于某种原因无法工作)。
  • 不需要匹配 ORACLE 数据库版本和客户端。规则是 ORACLE 客户端版本必须等于或高于 ORACLE 数据库。即使您的数据库版本是 10g,您也可以使用 OracleXE 11 中的客户端库。记住也要将包含目录切换到 ORACLEXE 11 - 否则您将获得 NULL 连接指针。
  • 所以我建议安装最后一个 OracleXE 11.2.0.2 oracle.com/technetwork/products/express-edition/downloads/… 并从以下位置获取适当的 OCCI 库:oracle.com/technetwork/database/occidownloads-083553.html 使用最后一个服务包(当前为 SP1)安装 MSVC2010 或快速版 microsoft.com/visualstudio/eng/products/… 在此我解决 std::string 堆损坏和应用程序在调试和发布模式下工作失败的方法。
  • 此外,您的应用程序必须与下载的 OCCI DLL 文件一起分发。
  • 好的,我同意升级 Oracle 比降级 IDE 更好(我做了什么)。将来,我会这样做。谢谢!
【解决方案2】:

大约一个月前,我重新审视了这个问题,发现 MSVC2010 occi 库是为 Oracle 11g 构建的。我们正在运行 Oracle 10g,所以我不得不使用 MSVC2005 库。所以我安装了过时的 IDE 并加载了 Debug 库并且它工作了(由于某种原因,发布版本不起作用)。

编辑

对于遇到相同问题的任何人,如果使用适当的库将 IDE 从 MSVC2010 降级到 MSVC2005 不起作用,您可以尝试将 Oracle 客户端从 10g 升级到 11g 并按照建议使用 MSVC2010 库由 harvyS.回想起来,这可能是更好的解决方案。

【讨论】:

    猜你喜欢
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多