Я искал эту ошибку в нескольких местах, и единственное, что я нашел, возможно, это проблема с диким указателем, но не знаю, как ее решить.
Вопрос заключается в том, что С++-коннектор отлично работает (после тяжелой работы) подключается к базе данных 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()
Изменить fld.assign(res- > getString (fldName)); to fld = res- > getString (имя_файла);
usr = getstr((char*)"User: ", -1, 128);
pw = new char[128];
pw = getstr((char *)"Password: ", '\0', 128);
Я не знаю, что делает getstr, но приведение строкового литерала к char * является немедленным признаком того, что вы собираетесь делать что-то очень, очень, неправильно. Вместо этого используйте функцию std::string и c_str(). Я также рассматриваю ваше множество удалений и ощущаю потенциал для плохих новостей прямо там - вы должны использовать указатель с областью для управления памятью, поскольку вы просите утечки.
Основываясь на ответе Стив Таунсенд, возможно, ваш цикл - это ваша проблема.
Следующий пример является хорошим примером цикла, потому что next()
получает вызов, сразу же перемещая внутренний курсор на первый элемент и заполняя его.
res = stmt->executeQuery("SELECT * FROM `estglob`");
while (res->next())
{
cout << "id = " << res->getString(1);
}
В вашем коде вы вызываете first()
, не вызывая next()
внутренне. Я полагаю, что функция first()
перемещает курсор на до начала, а первый вызов next()
перемещает внутренний курсор к первому элементу.
first()
- это перемотка курсора на наборе результатов, а не «перемотка и получение первого результата», это будет проблемой. Документы немного тонкие.
Я предполагаю, что вы используете 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, это потенциальная проблема.
Ты не одинок,
это недавняя проблема в 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
Новый код находится здесь:
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()