2010-11-19 3 views
0

여러 곳에서이 오류를 찾고 있었는데, 어쩌면 와일드 포인터 문제 일 수도 있지만 해결 방법을 알지 못합니다.C++ mysql sqlstring이 작동하지 않아서 0xC0000005 메모리를 읽을 수 없습니다.

질문은 C++ 커넥터가 잘 작동합니다 (열심히 노력한 후) mysql 데이터베이스에 연결하여 정보를 검색하지만 문자열 또는 sqlstring 유형을 사용할 때마다 (즉, 레코드 세트에서 정보를 가져올 수 없음) 여기

Not controlled exception at 0x5e477a8b (msvcp90d.dll) access violation when reading memory position at 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 방어 적이기 (서명 숯불의 *의 DST = 0x0031fa14, 서명 숯불의 *의 SRC = 0x00445355, 서명되지 않은 긴 계산 = 0x0000000f) 원격 교육 (314) 어셈블러에

msvcr90d.dll! memcpy_s (무효 * DST = 0x0031fa14, 부호 INT sizeInBytes = 0x0000000f, CONST 공극 *의 SRC = 0x00445355, 부호 INT 카운트 = 0x0000000f) 리니아 + 67 바이트 0x11을 C

msvcp90d.dll! 표준 : char_traits :: _ Copy_s (char * _First1 = 0x0031fa14, 부호없는 int _Size _size = INT _in_bytes = 0x0000000f, CONST * CHAR _First2 = 0x00445355, 부호 INT _COUNT = 0x0000000f) 리니아 582 + 0 * 16 바이트 C++

msvcp90d.dll! 표준 : _ Traits_helper :: copy_s> (* CHAR _First1 = 0x0031fa14, 부호 0x0000000f, CONST * CHAR _First2 = 0x00445355, 부호 INT _COUNT = 0x0000000f, 표준 : _ Secure_char_traits_tag __formal = {...}) 리니아 714 + 0x15 바이트 C++

msvcp90d.dll! 표준 : _ Traits_helper :: copy_s> (* CHAR _First1 = _size = 0x0000000f INT 0x0031fa14 부호를, CONST * CHAR _First2 = 0x00445355, 부호 INT _COUNT = 0x0000000f) 리니아 706 + 0x22 바이트 C++

msvcp90d.dll 표준 : basic_string, 표준 : 할당>! : : assign (const std :: basic_string, std :: a llocator> & _Right = erróneo, 부호없는 INT _Roff = 0x00000000의 서명되지 않은 INT _COUNT = 0xffffffff를) 원격 교육 1067 + 0x25로 바이트 C++

msvcp90d.dll 표준 : : basic_string, 표준 : : 할당이> : 지정 (const를 표준! : : basic_string, 표준 : 할당> = & _Right erróneo) 리니아 1,052 C++

testMySQL.exe wmain (INT는 argc = 0x00000001,은 wchar_t * argv를 = 0x00834a30) 리니아 0x8d 61 바이트 + C++

testMySQL!. exe! __ tmainCRTStartup() Línea 579 + 0x19 바이트 C

testMySQL.exe! wmainCRTStartup() Line 399 C

KERNEL32.DLL! 77,391,194()

[로스 마르코스 siguientes가 correctos O faltar없이 SE 한 cargado símbolos 파라 KERNEL32.DLL에는 산이 pueden 없음]
NTDLL.DLL! 77c7b495()
ntdll.dll! 77c7b468()

답변

0

변경 fld.assign [로스 마르코스 siguientes는 correctos O faltar없이 SE 한 cargado símbolos 파라 KERNEL32.DLL에는 산이 pueden 없음] (res-> getString (fldName)); fld = res-> getString (fldName);

+0

감사합니다! 해결 fld = res-> getString (fldName) .c_str(); – Miquel

+0

당신은 어떤 컴파일러를 사용하고 있습니까? –

+0

netbeans & cygwin을 사용하기 시작했지만 windows 통합 때문에 ms visual C++로 이동했습니다. – Miquel

1

여기에 MySql Connector/C++를 사용하고 있다고 가정합니다.이 반복이 문제이지만, 일반적으로이 발생할 경우

확실하지은 다음과 같습니다

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

이 결과 집합에 당신에게 첫 번째 열 확실 문자열 데이터를 포함? 논리 대신 색인 대신 열 이름을 사용하면 논리가 더 안정적이됩니다.

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

또 다른 가능성은 바이너리 MySql Connector/C++ 라이브러리를 사용하는 경우 빌드 된 Visual Studio와 다른 Visual Studio를 사용하고 있다는 것입니다. 이 경우, 귀하의 앱이 빌드 된 것과 동일한 VS를 사용하여 소스에서 MySql 라이브러리를 빌드 해 볼 수 있습니다. depends.exe를 MySql DLL과 EXE에서 사용하여 확인하십시오. 다른 MSVC * .DLL 버전을 참조하면 잠재적 인 문제 일 수 있습니다.

+0

(1); 왜냐하면 열 이름을 사용할 때 충돌이 발생하기 때문입니다. – Miquel

+0

제 생각에 여기 제안 된대로보다 전통적인 결과 반복 구조로 변환하면이 문제가 해결됩니다. 이유에 대한 @ Dean의 대답을 참조하십시오. 결과에 액세스하기 전에 next()를 호출해야합니다. –

+0

답변 해 주셔서 감사합니다. res-> getString (1);을 사용하고 있습니다. 왜냐하면 열 이름을 사용했을 때 충돌이 발생하기 때문입니다. 또한 라이브러리를 다시 작성하려고 시도했습니다 (노력이 많이되었습니다). 같은 것을 시도했을 때 눈치 챘습니다. \t 문자열 fld; \t char * fldName = "divisa"; \t \t nrows = res-> rowsCount(); \t \t if (nrows> 0) { \t \t \t res-> first(); (단째 <= NROWS; 행 행 ++ = 1) { \t \t \t \t \t FLD위한 \t \t.할당 (res-> getString (fldName)); \t \t \t \tcout << fld << endl; \t \t \t \t res-> next(); \t \t \t} \t \t} 이 충돌하지 않고 지금 문자열 문제를 찾고 .. 이상한 문자와 같은 somethinginmemory됩니다 .. – Miquel

1
usr = getstr((char*)"User: ", -1, 128); 
pw = new char[128]; 
pw = getstr((char *)"Password: ", '\0', 128); 

나는 getstr가 무엇을 알고 있지만, 숯불 *에 문자열 리터럴을 캐스팅하면 매우, 매우, 뭔가 잘못 할 겁니다 즉시 서명하지 않습니다. std :: string 및 c_str() 멤버 함수를 대신 사용하십시오. 나는 또한 당신의 과다한 삭제를보고 나쁜 소식에 대한 잠재력을 바로 느낄 것입니다. 당신이 누수를 구걸하는 것처럼 범위를 조정 한 포인터를 사용하여 메모리를 제어해야합니다.

+0

YE 때문에 문자열 관리에 대한 지식 부족 (C에서 항상 char * 및 calloc으로 바뀜)이 그물에있는 다른 코드에서 보았을 때 나는 그 길을 고수했다. – Miquel

1

스티브 타운젠드 (Steve Townsend)의 답변을 바탕으로 작성하면 아마도 루프가 문제가 될 수 있습니다.

다음은 좋은 루프 예제입니다. next()이 즉시 호출되어 내부 커서를 첫 번째 항목으로 이동하고 채 웁니다. 당신이 다음 next()를 호출하지 않고 first()를 호출하는 코드에

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

내부적으로 나는 first() 기능은 시작 및 next() 이동의 첫 번째 항목에 대한 내부 커서에 대한 첫 번째 호출하기 전에 로 커서를 이동 믿습니다.

+0

맞다. . 'first()'가 "되감기와 첫 번째 결과 얻기"가 아니라 결과 세트에서 커서를 되감기면 이것이 문제가됩니다. 워드 프로세서는 약간 얇습니다. –

+0

@Steve Townsend 게시하기 전에 문서를 확인하려고했으나 확인할 수 없습니다. –

+0

고마워, 그래서 그 방법도 시도뿐만 아니라 같은 문제 .. – Miquel

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 방어 적이기 (서명 숯불 * DST = 0x002bf794, 서명 숯불의 *의 SRC = 0x00445355, 부호 롱 카운트 = 0x0000000f) 리니아 314 어셈블러에

msvcr90d.dll! memcpy_s (보이드는 * DST = 0x002bf794, 부호 INT sizeInBytes = 0x0000000f, CONST 공극 *의 SRC = 0x00445355, 부호 INT 카운트 = 0x0000000f) 리니아 67 + 0x11을 바이트 C

01 23,516,

msvcp90d.dll! 표준 : char_traits :: _ Copy_s (* CHAR _First1 = 0x002bf794, 부호 INT _Size_in_bytes = 0x0000000f, CONST * CHAR _First2 = 0x00445355를 부호 INT _COUNT = 0x0000000f) 리니아 582 + 0 * 16 바이트 C++

msvcp90d .dll! std :: _ Traits_helper :: copy_s> (char * _First1 = 0x002bf794, unsigned int _Size = 0x0000000f, const char * _First2 = 0x00445355, 서명되지 않은 int _Count = 0x0000000f, std :: _ Secure_char_traits_tag __formal = {...}) Línea 714 + 0x15 바이트 C++

msvcp90d.dll! 표준 : _ Traits_helper :: copy_s> (* CHAR _First1 = 0x002bf794, _size = 0x0000000f INT 부호, 문자 CONST * _First2 = 0x00445355, 부호 INT _COUNT = 0x0000000f) + 706 리네아 0x22 바이트 C++

msvcp90d.dll!std :: basic_string, std :: allocator> :: const (const std :: basic_string, std :: allocator> & _Right = errone, unsigned int _Roff = 0x00000000, 부호없는 int _Count = 0xffffffff) 1067 + 0x25 바이트 C++

msvcp90d.dll! 표준 : : basic_string, 표준 : : 할당> :: 지정 (const를 표준 : : basic_string, 표준 : : 할당> & _Right = erróneo) 원격 교육 1052 C++

testMySQL.exe!의 wmain (INT ARGC = 0x00000001,은 wchar_t * argv를 = 0x008d4a30) 리니아 0x8d 65 바이트 + C++ testMySQL.exe! __ tmainCRTStartup() 리니아 579 바이트의 0x19 + C testMySQL.exe! wmainCRTStartup() 리니아 399 C KERNEL32.DLL! 77,391,194()

,451,515,


NTDLL.DLL! 77c7b495()
NTDLL.DLL! 77c7b468()

0

당신은 혼자가 아닙니다. 이것은 최근 Teeworldsddrace mod의 문제입니다. 그리고 내가 봤 거든 많은 다른 사람들이 (그냥 구글 : getString mysql 창) 같은 문제가 보았다.
getString은 varchar의 길이가 15자를 넘는 열의 값에 액세스 할 때 기본적으로 발생하며 mysql cpp 커넥터를 컴파일하는 데 사용한 것보다 다른 컴파일러를 사용하는 경우 올바른 (/ 동일한) 컴파일러를 선택해야합니다. 설정 (/ 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

는이 정보를 찾을 수 ... 여기에이 물건에 대해 읽을 수 있습니다 : 나는 RES->에는 getString 사용하고
http://bugs.mysql.com/bug.php?id=56742

+0

정보를 제공해 주셔서 감사합니다. 몇 달 전에이 문제를 해결 한 후 msvC++로 옮겼습니다. – Miquel

관련 문제