2010-11-19 21 views
0

Bu hatayı birkaç yerde arıyordum ve bulduğum tek şey belki de vahşi bir işaretçidir, ancak nasıl çözüleceğini bilmiyorum.C++ mysql sqlstring çöküyor 0xC0000005 belleği okuyamadı

Soru C++ bağlayıcı çalışıyor (sıkı çalıştıktan sonra) mysql veritabanına bağlanır, bilgi alır, ancak bu her zaman kilitlenir dize veya sqlstring türünü kullanır, (bu yüzden bilgileri kayıt kümesinden alamıyorum) İşte

Not controlled exception at 0x5e477a8b (msvcp90d.dll) access violation when reading memory position at 0x00445355.

kullanıyorum kodu: aynı hata

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

Herhangi bir öneri/yorum gerçekten iyi alınan olacak! Yani burada


hata noktasında callstack:

msvcr90d.dll memcpy (unsigned char * dst = 0x0031fa14, işaretsiz char * src = 0x00445355, imzasız uzun sayısı = 0x0000000f) Línea 314 makina dili

msvcr90d.dll! memcpy_s (void * dst = 0x0031fa14, imzasız int sizeInBytes = 0x0000000f, void * src = 0x00445355, imzasız int adet = 0x0000000f) Línea 67 + 0x11 bayt C

msvcp90d.dll! std :: char_traits :: _ Copy_s (char * _First1 = 0x0031fa14, imzasız int _Size _Size = int _in_bytes = 0x0000000f, const char * _First2 = 0x00445355, imzasız int _Count = 0x0000000f) Línea 582 + 0x16 bayt C++

msvcp90d.dll! Std :: _ Traits_helper :: copy_s> (char * _First1 = 0x0031fa14, imzasız 0x0000000f, const char * _First2 = 0x00445355, imzasız int _Count = 0x0000000f, std :: _ Secure_char_traits_tag __formal = {...}) Línea 714 + 0x15 bayt C++

msvcp90d.dll! std :: _ Traits_helper :: copy_s> (Char * _First1 = _Size = 0x0000000f int işaretsiz 0x0031fa14, const char * _First2 = 0x00445355, imzasız int _Count = 0x0000000f) Línea 706 + 0x22 bayt C++

msvcp90d.dll std :: basic_string, std :: allocator>!: : atama (const std :: basic_string, std :: a llocator> & _Right = erróneo, imzasız int _Roff = 0x00000000, imzasız int _Count = 0xffffffff) Línea 1067 + 0x25 bayt C++

msvcp90d.dll std :: basic_string, std :: allocator> :: atamak (const std!: : basic_string, std :: allocator> & _Right = erróneo) Línea 1052 C++

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

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

testMySQL.exe! wmainCRTStartup() Líne 399 ° C

kernel32.dll! 77391194()

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

cevap

0

değiştirme fld.assign [Los marcos siguientes correctos O faltar, no se han cargado símbolos para kernel32.dll bir ser pueden] (restorayon> getString (fldname)); fld = res-> getString (fldName);

+0

Bir milyon teşekkürler! Fld = res-> getString (fldName) .c_str() ile çözüldü; – Miquel

+0

Sadece hangi derleyiciyi kullandığınızı referans olarak kabul edersiniz. –

+0

netbeans & cygwin kullanmaya başladım ama windows entegrasyonu nedeniyle ms visual C++ 'ye taşındım – Miquel

1

Burada MySql Connector/C++ kullandığınızı kabul ediyorum.Bu yineleme sorun, ama tipik sonucu ise

emin değil şuna benzer:

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

sizin sonuç kümesindeki size ilk sütun emin dize verileri içerir? Mantığınız, dizin yerine sütun adı kullanılarak daha güvenilir olacaktır.

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

başka olasılık ikili MySQL Connector/C++ kütüphaneleri kullanıyorsanız, bunların inşa edilmiş olandan farklı bir Visual Studio kullanarak olmasıdır. Uygulamanızla aynı VS'yi kullanarak MySql lib'lerini kaynaktan oluşturmayı deneyebilirsiniz, durum buysa. Bunu MySql DLL'lerinde ve EXE'inizde depends.exe kullanarak kontrol edin - eğer farklı MSVC * .DLL sürümlerini kullanıyorlarsa, bu potansiyel bir problemdir.

+0

(1); çünkü sütun adı ile yaptığım zaman da çöker. – Miquel

+0

Tahminimce, burada önerildiği gibi daha geleneksel sonuç yineleme yapısına dönüştürmek bunu düzeltecektir. @ Dekanın cevabı neden? Bir sonuca erişmeden önce next() 'i çağırmalısınız. –

+0

Cevabınız için teşekkürler. Res-> getString (1) kullanıyorum; çünkü sütun adıyla yaptığım zaman da çöker. Ayrıca kütüphaneleri yeniden oluşturmaya çalıştı (bu zor işti). \t string fld; \t char * fldName = "divisa"; \t \t nrows = res-> rowsCount(); \t \t eğer (nrows> 0) { \t \t \t res-> first(); (; Satır <= nrows; satır ++ satır = 1) { \t \t \t \t fld için \t \t \t.atamak (res-> getString (fldname)); \t \t \t \t cout << fld << endl; \t \t \t res-> next(); \t \t \t} \t \t} O çökmez ama şimdi dize problemleri üzerinde seyir .. garip karakterler gibi somethinginmemory alır .. – Miquel

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

Ben getstr ne yaptığını biliyorum, ama bir char * için birebir bir dize döküm Çok, çok, yanlış bir şey yapacağız acil işarettir yoktur. Bunun yerine std :: string ve c_str() üye işlevini kullanın. Ayrıca çok sayıda silmeye bakıyorum ve oradaki kötü haber potansiyelini hissediyorum - sızıntı için yalvarıyorsunuz diye hafızayı kontrol etmek için kapsamlı bir işaretçi kullanmalısınız.

+0

YEs, bu yüzden değişti .. dizeleri yönetme konusunda bilgi eksikliğim (C'den geliyorum her zaman char * ve calloc) böylece ağdaki diğer kodlarda gördüğümde bunun yolunu aldım .. – Miquel

1

Steve Townsend'in cevabının üzerine inşa edilmesi belki de sizin sorunlarınızdır.

Aşağıdaki örnek, iyi bir döngü örneğidir; çünkü next() iç imleci hemen ilk öğeye taşıyarak ve doldururken çağrılır. Sonra next() uğramadan first() aradığınız Kodunuzda

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

içten ben first() fonksiyonu başladıktan ve next() hamle ilk öğeye iç imleç için ilk kullanımdan önce imleci hareket inanıyoruz.

+0

Evet doğru geliyor . İlk() ', sonuç kümesindeki imlecin geri sarmasıysa," geri sar ve ilk sonucu al "değil, sorun bu olur. Dokümanlar biraz zayıf. –

+0

@Steve Townsend Göndermeden önce dokümanları kontrol etmeye çalıştım ama doğrulamak için onları bulamadım. –

+0

Teşekkürler, ben de aynı şekilde denedim, ama aynı sorun .. – Miquel

0

yeni kod burada:

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

Ve burada hata noktasında callstack:

msvcr90d.dll memcpy (unsigned char * dst = 0x002bf794, işaretsiz char * src = 0x00445355, imzasız uzun sayısı = 0x0000000f) Línea 314 Asm

msvcr90d.dll! memcpy_s (void * dst = 0x002bf794, imzasız int sizeInBytes = 0x0000000f, void * src = 0x00445355, imzasız int adet = 0x0000000f) Línea 67 + 0x11 bayt C

msvcp90d.dll! Std :: char_traits :: _ Copy_s (char * _First1 = 0x002bf794, imzasız int _Size_in_bytes = 0x0000000f, const char * _First2 = 0x00445355, imzasız int _Count = 0x0000000f) Línea 582 + 0x16 bayt C++

msvcp90d .dll! std :: _ Traits_helper :: copy_s> (char * _First1 = 0x002bf794, imzasız int _Size = 0x0000000f, const char * _First2 = 0x00445355, imzasız int _Count = 0x0000000f, std :: _ Secure_char_traits_tag __formal = {...}) Línea 714 + 0x15 bayt C++

msvcp90d.dll! std :: _ Traits_helper :: copy_s> (char * _First1 = 0x002bf794, _Size = 0x0000000f int işaretsiz, const char * _First2 = 0x00445355, imzasız int _Count = 0x0000000f) Línea 706 + 0x22 bayt C++

msvcp90d.dll!std :: basic_string, std :: allocator> :: atama (const std :: basic_string, std :: ayırıcı> & _Right = erróneo, unsigned int _Roff = 0x00000000, imzasız int _Count = 0xffffffff) Línea 1067 + 0x25 bayt C++

msvcp90d.dll! std :: basic_string, std :: allocator> :: atamak (const std :: basic_string, std :: allocator> & _Right = erróneo) Línea 1052 C++

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


ntdll.dll! 77c7b495()
ntdll.dll! 77c7b468()

0

Yalnız değilsiniz,
bu, Teeworldsddrace mod da yeni bir sorundur. Ve ben googled olarak ben birçok başkalarının aynı soruna sahip olduğunu gördüm (sadece google: getString mysql windows).
Temelde, getString, varchar'ın 15 karakterden uzun olan bir sütunun değerine eriştiğinde ve uygulamanız için farklı bir derleyici kullanıyorsanız, mysql cpp konektörünü derlemek için kullandığınızdan da doğru (/ aynı) bir derleyiciyi seçmeniz gerektiğinde olur ayarlar (/ MD,/MDd,/MT,/MTd). Yaklaşık var VC90.CRT ile mysql cpp 1.0.5 bağlayıcılar inşa ve diğerleri VC80.CRT ile inşa. Sen
Why do I need to know?
CAUTION: binary compatibility on Windows

bu bilgileri bulundu ... Burada bu konu hakkında bilgi edinebilirsiniz: Ben res-> getString kullanıyorum
http://bugs.mysql.com/bug.php?id=56742

+0

Bilgi için teşekkürler. Birkaç ay önce bunu çözdüm, sonra msvC++'ye geçtim ve daha iyi çalıştı. – Miquel

İlgili konular