代码之家  ›  专栏  ›  技术社区  ›  Miquel

C++MySQL SqLoad崩溃0xC090005无法读取内存[关闭]

  •  0
  • Miquel  · 技术社区  · 14 年前

    我在几个地方寻找这个错误,唯一发现的可能是一个疯狂的指针问题,但不知道如何解决。

    问题是C++连接器工作得很好(经过辛勤工作)连接到MySQL数据库,检索信息,但是每次使用字符串或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);
    }
    

    任何建议/意见都会得到很好的采纳!


    这里是错误点的调用堆栈:

    MSVCR90DLL!memcpy(无符号char*dst=0x0031fa14,无符号char*src=0x00445355,无符号long count=0x000000f)l_-nea 314 asm

    MSVCR90DLL!memcpy_s(void*dst=0x0031fa14,unsigned int sizeinbytes=0x000000f,const void*src=0x00445355,unsigned int count=0x000000f)l_-nea 67+0x11 bytes c

    MSVCP90DLL!STD::CARUX特性::Cyr*FixST1= 0x03FA14,未签名INTSIEZIN INSyBys= 0x000 000 0F,const char *FixST2=0x4445 355,未签名int t计数=0x000 000 0F)LαNEA 582 +0x16字节C++

    MSVCP90DLL!STD::CopySuthsHelp:(char *FixST1= 0x03FA14,未签名int大小=0x000 000 0F,const char *FixST2=0x4445 355,未签名int t计数=0x000 000 0F,STD::γSECURA TRAITSITY标签Type={}…})LαNEA 714 +0x15字节C++

    MSVCP90DLL!STD::TraceStHelp::Copy*FixST1= 0x03FA14,未签名int大小=0x000 000 0F,conchch**FixST2= 0x0445 355,未签名int t计数=0x000 000 0F)LαNEA 706 +0x22字节C++

    MSVCP90DLL!STD::Basic字符串,STD::分配器和gt;::赋值(const ST::Basic字符串,STD::分配器和gt;=Err.O.Neo,无符号int yROFF=0x90000,未签名int t计数=0xFFFFFFFF)LαNEA 1067 +0x25字节C++

    MSVCP90DLL!STD::Basic字符串,STD::分配器& gt;::赋值(const STD::Basic字符串,STD::分配器和gt;

    ExtMySq.L.EXE!WMIN(INTARC=0x00 000,01,WCHARYT**ARGV= 0x00 834 A30)LαNEA 61 +0x8D字节C++

    ExtMySq.L.EXE!_ tmaincrtstartup()l_-nea 579+0x19字节c

    ExtMySq.L.EXE!wmaincrtstartup()l_-nea 399 C

    KNEL32.DLL!7891194-()

    [los marcos siguientes pueden no ser correctos o faltar,no se han cargado s_-mbolos para kernel32.dll]
    NTDLL.DLL!7C7B45-()
    NTDLL.DLL!7C7B468()

    6 回复  |  直到 9 年前
        1
  •  0
  •   Luis G. Costantini R.    14 年前

    将fld.assign(res->getstring(fldname));更改为fld=res->getstring(fldname);

        2
  •  1
  •   Steve Townsend    14 年前

    我假设你在这里使用MySQL连接器/C++。

    不确定这是否是问题所在,但通常结果迭代如下:

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

    您确定结果集中的第一列包含字符串数据吗?您的逻辑将更可靠地使用列名而不是其索引。

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

    另一种可能性是,如果使用二进制MySQL连接器/C++库,则使用的是不同的VisualStudio而不是它们所构建的。如果是这样的话,你可以尝试使用与你的应用程序相同的vs从源代码构建mysql libs。使用依赖于mysql dll和您的exe的depends.exe检查此问题-如果它们引用不同的msvc*.dll版本,则这是一个潜在的问题。

        3
  •  1
  •   Puppy    14 年前
    usr = getstr((char*)"User: ", -1, 128);
    pw = new char[128];
    pw = getstr((char *)"Password: ", '\0', 128);
    

    我不知道getstr是做什么的,但是将字符串文字转换成char*是一个直接的信号,表明您将要做一些非常、非常、错误的事情。请改用std::string和c_str()成员函数。我还查看了您的大量删除,并感觉到有可能出现坏消息——您应该使用一个范围指针来控制内存,因为您在请求泄漏。

        4
  •  1
  •   Dean Taylor    14 年前

    根据史蒂夫汤森的回答,也许你的循环就是你的问题。

    下面是一个很好的循环示例,因为 next() 立即调用,将内部光标移动到第一个项并填充它。

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

    在您的代码中,您正在呼叫 first() 不打电话 下() 在内部我相信 第一() 函数将光标移动到 开始前 第一次打电话给 下() 将内部光标移到第一项。

        5
  •  0
  •   Miquel    14 年前

    新代码如下:

    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);
    

    这里是错误点的调用堆栈:

    MSVCR90DLL!memcpy(无符号char*dst=0x002bf794,无符号char*src=0x00445355,无符号long count=0x000000f)l_-nea 314 asm

    MSVCR90DLL!memcpy_s(void*dst=0x002bf794,unsigned int sizeinbytes=0x000000f,const void*src=0x00445355,unsigned int count=0x000000f)l_-nea 67+0x11 bytes c

    MSVCP90DLL!STD::CARUX特性::Cyr*FixST1= 0x02BF7949,未签名INTSIEZIN INSyBys= 0x000 000 0F,const char *FixST2=0x4445 355,未签名int t计数=0x000 000 0F)LαNEA 582 +0x16字节C++

    MSVCP90DLL!STD::CopySuthsHelp:(char *FixST1= 0x02BF7949,未签名int大小=0x000 000 0F,conchch**FixST2= 0x0445 355,未签名int t计数=0x000 000 0F,STD:::SyraceSchulaTrITSsTyAgType={…})LαNEA 714 +0x15字节C++.

    MSVCP90DLL!STD::TraceTsIHelp::(ch**FixST1= 0x02bf7949,未签名int大小=0x000 000 0f,conchch**FixST2= 0x0445 355,未签名int t计数=0x000 000 0F)LαNEA 706 +0x22字节C++

    MSVCP90DLL!STD::Basic字符串,STD::分配器和gt;::赋值(const ST::Basic字符串,STD::分配器和gt;=Err.O.Neo,无符号int yROFF=0x90000,未签名int t计数=0xFFFFFFFF)LαNEA 1067 +0x25字节C++

    MSVCP90DLL!STD::Basic字符串,STD::分配器& gt;::赋值(const STD::Basic字符串,STD::分配器和gt;

    ExtMySq.L.EXE!WMIN(INTARC=0x000 000 01,WCHARYT**ARGV= 0x00 8D4A30)LαNEA 65 +0x8D字节C++ ExtMySq.L.EXE!_ tmaincrtstartup()l_-nea 579+0x19字节c ExtMySq.L.EXE!wmaincrtstartup()l_-nea 399 C KNEL32.DLL!7891194-()

    [los marcos siguientes pueden no ser correctos o faltar,no se han cargado s_-mbolos para kernel32.dll]
    NTDLL.DLL!7C7B45-()
    NTDLL.DLL!7C7B468()

        6
  •  0
  •   Allisone    14 年前

    你并不孤单,
    这是最近的一个问题 Teeworlds ddrace 莫德也。当我在谷歌上搜索的时候,我发现很多其他人也有同样的问题(只是google for:getstring mysql windows)。
    当getstring访问varchar长度超过15个字符的列的值时,基本上会发生这种情况,如果您的应用程序使用的编译器与用于编译mysql cpp connector的编译器不同,那么您还需要选择正确的(/same)编译器设置(/md,/mdd,/mt,/mtd)。有f.e.mysql cpp 1.0.5连接器用vc90.crt构建,其他连接器用vc80.crt构建。 你可以在这里读到这些东西…
    Why do I need to know?
    CAUTION: binary compatibility on Windows

    在以下位置找到此信息:
    http://bugs.mysql.com/bug.php?id=56742