c ++ mysql sqlstring аварийно завершает работу 0xC0000005, не удается прочитать память

0

Я искал эту ошибку в нескольких местах, и единственное, что я нашел, возможно, это проблема с диким указателем, но не знаю, как ее решить.

Вопрос заключается в том, что С++-коннектор отлично работает (после тяжелой работы) подключается к базе данных mysql, извлекает информацию, но каждый раз, когда используется тип string или sqlstring, он сбой (поэтому я не могу получить информацию из набора записей) ошибка:

Неконтролируемое исключение при 0x5e477a8b (msvcp90d.dll), когда считывание позиции памяти в 0x00445355.

Вот код, который я использую:

int main() {

    Driver *driver;
    Connection *con;
    Statement *stmt;
    ResultSet *res;
    string fld;
    char *fldName = "divisa";

    int row=1, nrows=0;
    char *url, *database, *usr, *pw;

    url = DBHOST;
    database = DATABASE;
    usr = getstr("User: ", -1, 128); // char* getstr(char prompt[], char chReplace, int maxLen);
    pw = new char[128];
    pw = getstr("Password: ", '\0', 128);
    cout << endl;

    try {
        driver = get_driver_instance();
        con = driver->connect(url, usr, pw);
        pw = new char[128];
        con->setAutoCommit(0);
        con->setSchema(database);
        stmt = con->createStatement();

        res = stmt->executeQuery("SELECT * FROM `estglob`");

        while(res->next()) {    
            fld.assign(res->getString(fldName));
            cout << fld << endl;
        }

        _getch();
        cout << endl << "Cleaning up the resources .." << endl;

        delete res;
        delete stmt;
        con -> close();
        delete con;
    }
    catch (SQLException &e) {
        cout << endl << "ERROR: SQLException in " << __FILE__;
        cout << " (" << __FUNCTION__<< ") on line " << __LINE__ << endl;
        cout << "ERROR: " << e.what();
        cout << " (MySQL error code: " << e.getErrorCode() << ")";
        cout << ", SQLState: " << e.getSQLState() << ")" << endl; // <== CRASH here

        _getch();
        return(EXIT_FAILURE);
    }
    catch (std::runtime_error &e)
    {
        cout << "ERROR: runtime_error in " << __FILE__;
        cout << " (" << __FUNCTION__ << ") on line " << __LINE__ << endl;
        cout << "ERROR: " << e.what() << endl;

        _getch();
        return(EXIT_FAILURE);
    }

    return(EXIT_SUCCESS);
}

Любое предложение/комментарии будет действительно хорошо воспринято!


Итак, вот столбец при ошибке:

msvcr90d.dll! memcpy (unsigned char * dst = 0x0031fa14, unsigned char * src= 0x00445355, unsigned long count = 0x0000000f) Línea 314 Asm

msvcr90d.dll! memcpy_s (void * dst = 0x0031fa14, unsigned int sizeInBytes = 0x0000000f, const void * src= 0x00445355, unsigned int count = 0x0000000f) Línea 67 + 0x11 bytes C

msvcp90d.dll! std:: char_traits:: _ Copy_s (char * _First1 = 0x0031fa14, unsigned int _Size_in_bytes = 0x0000000f, const char * _First2 = 0x00445355, unsigned int _Count = 0x0000000f) Línea 582 + 0x16 байт С++

msvcp90d.dll! std:: _ Traits_helper:: copy_s > (char * _First1 = 0x0031fa14, unsigned int _Size = 0x0000000f, const char * _First2 = 0x00445355, unsigned int _Count = 0x0000000f, std:: _ Secure_char_traits_tag __formal = {...}) Línea 714 + 0x15 байт С++

msvcp90d.dll! std:: _ Traits_helper:: copy_s > (char * _First1 = 0x0031fa14, unsigned int _Size = 0x0000000f, const char * _First2 = 0x00445355, unsigned int _Count = 0x0000000f) Línea 706 + 0x22 байт С++

msvcp90d.dll! std:: basic_string, std:: allocator > :: assign (const std:: basic_string, std:: allocator > и _Right = erróneo, unsigned int _Roff = 0x00000000, unsigned int _Count = 0xffffffff) Línea 1067 + 0x25 байт С++

msvcp90d.dll! std:: basic_string, std:: allocator > :: assign (const std:: basic_string, std:: allocator > и _Right = erróneo) Línea 1052 С++

testMySQL.exe! wmain (int argc = 0x00000001, wchar_t * * argv = 0x00834a30) Línea 61 + 0x8d bytes С++

testMySQL.exe! __ tmainCRTStartup() Línea 579 + 0x19 байт C

testMySQL.exe! wmainCRTStartup() Línea 399 C

kernel32.dll! 77391194()

[Los marcos siguientes pueden no ser correctos o faltar, no se han cargado símbolos para kernel32.dll]
ntdll.dll! 77c7b495()
ntdll.dll! 77c7b468()

Теги:
string

6 ответов

0
Лучший ответ

Изменить fld.assign(res- > getString (fldName)); to fld = res- > getString (имя_файла);

  • 0
    Бесконечно благодарен!! Решается с помощью fld = res-> getString (fldName) .c_str ();
  • 0
    Пожалуйста, только для справки, какой компилятор вы используете?
Показать ещё 1 комментарий
1
usr = getstr((char*)"User: ", -1, 128);
pw = new char[128];
pw = getstr((char *)"Password: ", '\0', 128);

Я не знаю, что делает getstr, но приведение строкового литерала к char * является немедленным признаком того, что вы собираетесь делать что-то очень, очень, неправильно. Вместо этого используйте функцию std::string и c_str(). Я также рассматриваю ваше множество удалений и ощущаю потенциал для плохих новостей прямо там - вы должны использовать указатель с областью для управления памятью, поскольку вы просите утечки.

  • 0
    Да, поэтому я изменился .. мои нехватки знаний в управлении строками (я пришел из C, поэтому всегда char * и calloc), поэтому, когда я увидел в другом коде в сети, я предположил, что это был путь ..
1

Основываясь на ответе Стив Таунсенд, возможно, ваш цикл - это ваша проблема.

Следующий пример является хорошим примером цикла, потому что next() получает вызов, сразу же перемещая внутренний курсор на первый элемент и заполняя его.

res = stmt->executeQuery("SELECT * FROM `estglob`");
while (res->next()) 
{
    cout << "id = " << res->getString(1);
}

В вашем коде вы вызываете first(), не вызывая next() внутренне. Я полагаю, что функция first() перемещает курсор на до начала, а первый вызов next() перемещает внутренний курсор к первому элементу.

  • 0
    Да, это звучит правильно. Если first() - это перемотка курсора на наборе результатов, а не «перемотка и получение первого результата», это будет проблемой. Документы немного тонкие.
  • 0
    @Steve Townsend Я пытался проверить документы перед публикацией, но не смог найти их для проверки.
Показать ещё 1 комментарий
1

Я предполагаю, что вы используете MySql Connector/С++ здесь.

Не уверен, что это проблема, но, как правило, результат выглядит так:

res = stmt->executeQuery("SELECT * FROM `estglob`");
while (res->next()) 
{
  cout << "id = " << res->getString(1);
}

Вы уверены, что первый столбец в вашем результирующем наборе содержит строковые данные? Ваша логика будет более надежной, используя имя столбца, а не его индекс.

  cout << "id = " << res->getString("nameOfColumnWithStringData");

Другая возможность заключается в том, что если вы используете двоичные библиотеки MySql Connector/С++, вы используете другую Visual Studio, чем то, с чем они были построены. Вы можете попытаться создать библиотеки MySql из источника, используя тот же VS, что и ваше приложение, если это произойдет. Проверьте это, используя depend.exe в DLL MySql и на EXE - если они ссылаются на разные версии MSVC *.DLL, это потенциальная проблема.

  • 0
    Я использовал res-> getString (1); потому что, когда я делаю с именем столбца также вылетает.
  • 0
    Я предполагаю, что преобразование в более традиционную итерационную конструкцию результата, как предложено здесь, исправит это. Смотрите @ ответ Дина, почему. Вы должны вызвать next (), прежде чем получить доступ к результату.
Показать ещё 4 комментария
0

Ты не одинок,
это недавняя проблема в Teeworlds ddrace мод тоже. И поскольку я googled, я видел, что у многих других была такая же проблема (просто google для: getString mysql windows).
В основном это происходит, когда getString обращается к значению столбца с varchar длиной более 15 символов, и если вы используете другой компилятор для своего приложения, чем для компиляции соединителя mysql cpp, вам также нужно выбрать правильные (/такие же) настройки компилятора (/MD,/MDd,/MT,/MTd). Есть f.e. Разъемы mysql cpp 1.0.5 построены с помощью VC90.CRT, а другие - с VC80.CRT. Вы можете прочитать об этом здесь...
Почему мне нужно знать?
ПРЕДОСТЕРЕЖЕНИЕ: двоичная совместимость в Windows

Нашли эту информацию по адресу: http://bugs.mysql.com/bug.php?id=56742

  • 0
    Спасибо за информацию. Я решил это несколько месяцев назад, затем перешел на msvc ++, и он работал лучше.
0

Новый код находится здесь:

Driver *driver;
Connection *con;
Statement *stmt;
ResultSet *res;
string fld;
char *fldName = "divisa";

int i;
char *url, *database, *usr, *pw;

url = (char *) calloc(256, sizeof(char));
database = (char *) calloc(64, sizeof(char));
usr = (char *) calloc(64, sizeof(char));
pw = (char *) calloc(64, sizeof(char));

url = DBHOST;
database = DATABASE;
usr = getstr("User: ", -1, 64); // Get user home made function
pw = getstr("Password: ", '\0', 64); // Get password home made function
cout << endl;

try {
    driver = get_driver_instance();
    con = driver->connect(url, usr, pw); // create a database connection using the Driver
    for (i=0; i<64; i++) pw[i] = '\0';

    con->setAutoCommit(0); // turn off the autocommit
    con->setSchema(database); // select appropriate database schema
    stmt = con->createStatement(); // create a statement object

    res = stmt->executeQuery("SELECT * FROM `estglob`");

    while(res->next()) {    
        fld.assign(res->getString(fldName));
        cout << fld;
    }

    _getch();
    cout << endl << "Cleaning up the resources .." << endl;

    // Clean up
    con -> close();
    free(res);
    free(driver);
    free(con);
    free(stmt);
}
catch (SQLException &e) {
    cout << endl << "ERROR: SQLException in " << __FILE__;
    cout << " (" << __FUNCTION__<< ") on line " << __LINE__ << endl;
    cout << "ERROR: " << e.what();
    cout << " (MySQL error code: " << e.getErrorCode() << ")";
    //cout << ", SQLState: " << e.getSQLState() << ")" << endl;

    if (e.getErrorCode() == 1047)
    {
        //
        // Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR)
        // Message: Unknown command

        cout << "\nYour server does not seem to support Prepared Statements at all. ";
        cout << "Perhaps MYSQL < 4.1?" << endl;
    }

    _getch();
    return(EXIT_FAILURE);
}
catch (std::runtime_error &e)
{
    cout << "ERROR: runtime_error in " << __FILE__;
    cout << " (" << __FUNCTION__ << ") on line " << __LINE__ << endl;
    cout << "ERROR: " << e.what() << endl;

    _getch();
    return(EXIT_FAILURE);
}

return(EXIT_SUCCESS);

И вот столбец при ошибке:

msvcr90d.dll! memcpy (unsigned char * dst = 0x002bf794, unsigned char * src= 0x00445355, unsigned long count = 0x0000000f) Línea 314 Asm

msvcr90d.dll! memcpy_s (void * dst = 0x002bf794, unsigned int sizeInBytes = 0x0000000f, const void * src= 0x00445355, unsigned int count = 0x0000000f) Línea 67 + 0x11 bytes C

msvcp90d.dll! std:: char_traits:: _ Copy_s (char * _First1 = 0x002bf794, unsigned int _Size_in_bytes = 0x0000000f, const char * _First2 = 0x00445355, unsigned int _Count = 0x0000000f) Línea 582 + 0x16 байт С++

msvcp90d.dll! std:: _ Traits_helper:: copy_s > (char * _First1 = 0x002bf794, unsigned int _Size = 0x0000000f, const char * _First2 = 0x00445355, unsigned int _Count = 0x0000000f, std:: _ Secure_char_traits_tag __formal = {...}) Línea 714 + 0x15 байт С++

msvcp90d.dll! std:: _ Traits_helper:: copy_s > (char * _First1 = 0x002bf794, unsigned int _Size = 0x0000000f, const char * _First2 = 0x00445355, unsigned int _Count = 0x0000000f) Línea 706 + 0x22 байт С++

msvcp90d.dll! std:: basic_string, std:: allocator > :: assign (const std:: basic_string, std:: allocator > и _Right = erróneo, unsigned int _Roff = 0x00000000, unsigned int _Count = 0xffffffff) Línea 1067 + 0x25 байт С++

msvcp90d.dll! std:: basic_string, std:: allocator > :: assign (const std:: basic_string, std:: allocator > и _Right = erróneo) Línea 1052 С++

testMySQL.exe! wmain (int argc = 0x00000001, wchar_t * * argv = 0x008d4a30) Línea 65 + 0x8d байт С++ testMySQL.exe! __ tmainCRTStartup() Línea 579 + 0x19 байт C testMySQL.exe! wmainCRTStartup() Línea 399 C kernel32.dll! 77391194()

[Los marcos siguientes pueden no ser correctos o faltar, no se han cargado símbolos para kernel32.dll]
ntdll.dll! 77c7b495()
ntdll.dll! 77c7b468()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню