Нарушение прав доступа Ошибка при отображении строки простого запроса Oracle (VS10 Exp C ++)

Я борюсь с проблемой, связанной с запуском оператора SQL в базе данных Oracle через C ++, используя occi. Мой код выглядит следующим образом:

#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;
}

Отображаемая ошибка:

Необработанное исключение в 0x1048ad7a (msvcp100d.dll) в MyDatabaseApp.exe: 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)

Надеюсь, я не запутал слишком много информации ... Любая помощь или понимание было бы замечательно, заранее спасибо!

ИЗМЕНИТЬ Если я переписываю свой цикл, сохраняя значение в локальной переменной, в конце цикла выдается ошибка:

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

person souldzin    schedule 14.02.2013    source источник
comment
Что, если вы назначите rs- ›getString (1) локальной строковой переменной, чтобы проверить ее в отладчике? Что это показывает?   -  person OldProgrammer    schedule 15.02.2013
comment
@LeorA Это была моя первая мысль. Итак, если я создаю локальную переменную и присваиваю ее значение 'rs- ›getString (1)', это значение равно 1 (как и ожидалось), и оно распечатывается, но я получаю ту же ошибку при закрытии} цикла ...   -  person souldzin    schedule 15.02.2013
comment
Похоже какая-то проблема с повреждением памяти. Удачи.   -  person OldProgrammer    schedule 15.02.2013


Ответы (2)


Обычно такие проблемы возникают из-за различий в средах сборки (IDE) конечного пользователя и поставщика.

Проверьте это.

Связанные проблемы:

Сначала попробуйте использовать правильную библиотеку и dll. Если скомпилирован в режиме отладки, то все библиотеки и dll должны быть отладочными. Используйте представление VC ++ Modules, чтобы убедиться, что загружена правильная DLL.

Мне повезло с моим приложением: все библиотеки были скомпилированы для MSVC2010. Поэтому я просто проверяю библиотеки DLL режима отладки и выпуска и получаю рабочее приложение.

person harvyS    schedule 02.07.2013
comment
Спасибо за ссылки, около месяца назад я вернулся к этому вопросу и обнаружил, что библиотека MSVC2010 используется только для oracle 11g. Мы используем 10g, поэтому я установил MSVC2005 и загрузил соответствующую библиотеку отладки, и она сработала (библиотека режима выпуска по какой-то причине не работала). - person souldzin; 02.07.2013
comment
Необязательно сопоставлять версию базы данных ORACLE и клиент. Правило состоит в том, что версия клиента ORACLE должна быть не ниже версии базы данных ORACLE. Даже если у вас версия базы данных 10g, вы можете использовать клиентские библиотеки из OracleXE 11. Не забудьте переключить каталог include на ORACLEXE 11 - в противном случае вы получите NULL указатель соединения. - person harvyS; 03.07.2013
comment
Поэтому я предлагаю установить последнюю версию OracleXE 11.2.0.2 oracle.com/ technetwork / products / express-edition / downloads /, а затем взять соответствующие библиотеки OCCI из: oracle.com/technetwork/database/occidownloads-083553.html Установите MSVC2010 с последним пакетом обновления (в настоящее время SP1) или экспресс-выпуском microsoft.com/visualstudio/eng/products/ Таким образом я решил свои проблемы с повреждениями кучи std :: string и приложением работает в режиме отладки и выпуска. - person harvyS; 03.07.2013
comment
Также ваше приложение должно распространяться с загруженными DLL-файлами OCCI. - person harvyS; 03.07.2013
comment
Хорошо, я согласен, что лучше обновить Oracle, чем понизить версию IDE (что я сделал). В будущем сделаю это. Спасибо! - person souldzin; 03.07.2013

Я вернулся к этому вопросу около месяца назад и обнаружил, что библиотека occi MSVC2010 была создана для Oracle 11g. Мы используем Oracle 10g, поэтому мне пришлось использовать библиотеку MSVC2005. Итак, я установил устаревшую IDE и загрузил библиотеку Debug, и она заработала (хотя по некоторым причинам релизная версия не работала).

ИЗМЕНИТЬ

Для тех, у кого такая же проблема, как и у меня, если понижение версии IDE с MSVC2010 до MSVC2005 с соответствующими библиотеками не работает, вы можете попробовать обновить клиент Oracle с 10g до 11g и использовать библиотеку MSVC2010, как предлагает harvyS. Оглядываясь назад, возможно, это было бы лучшим решением.

person souldzin    schedule 02.07.2013