crash - MySQL C++ Connector crashes my app at ResultSet->getString() -


it's me again asking noob c++ questions

i had major headaches making darn (sorry language) mysql c++ connector work. don't know if poorly written or something, experience yet i've never had trouble making work.

anyhow got connect , throw exceptions on failed connect/query me quite big thing :u :p . actual problem comes out of me obtaining result of query. regardless of application crashes :s

i used 32-bit installer , libmysql.dll/lib 32-bit mysql server (since i'm compiling 32-bit application figured right thing do)

here's code imagine i'm talking about

dbmanager.h

#ifndef dbmanager_h #define dbmanager_h #define cppconn_public_func #define cppconn_lib_build true  #include <string> #include "mysql_connection.h" #include "mysql_driver.h" #include <cppconn/driver.h> #include <cppconn/exception.h> #include <cppconn/resultset.h> #include <cppconn/statement.h> #include <cppconn/prepared_statement.h>  class dbmanager { public:     static dbmanager* instance();     bool query(const char* query);     void connect(const char* dbhost, unsigned short dbport, const char* dbuser, const char* dbpass, const char* dbname);     bool validcredentials(const char* username, const char* password);     void manageexception(sql::sqlexception &e);      ~dbmanager();  protected:     static dbmanager* pinstance;  private:     dbmanager() {};     dbmanager(dbmanager const&){};     dbmanager& operator=(dbmanager const&){};      sql::mysql::mysql_driver* driver;     sql::connection *con;     sql::preparedstatement *pstmt;     sql::resultset *res;     sql::statement *stmt;      bool isconnected; };  #endif 

and cpp file dbmanager.cpp

#include "dbmanager.h"  dbmanager* dbmanager::pinstance = null;  dbmanager* dbmanager::instance() {     if (!pinstance)     {         pinstance = new dbmanager();     }      return pinstance; }  bool dbmanager::query(const char* query) {     return true; }  dbmanager::~dbmanager() {        delete con;     delete pstmt;     delete res;     delete stmt; }  void dbmanager::manageexception(sql::sqlexception& e) {     if (e.geterrorcode() != 0) {         std::cout << "# err: sqlexception in " << __file__;         std::cout << "(" << __function__ << ") on line " << __line__ << std::endl;         std::cout << "# err: " << e.what();         std::cout << " (mysql error code: " << e.geterrorcode();         std::cout << ", sqlstate: " << e.getsqlstate() << " )" << std::endl;     } }  void dbmanager::connect(const char* dbhost, unsigned short dbport, const char* dbuser, const char* dbpass, const char* dbname) {     try {         driver = sql::mysql::get_mysql_driver_instance();         std::string conndsn = "tcp://" + std::string(dbhost) + ":3306";          con = driver->connect(conndsn, sql::sqlstring(dbuser), sql::sqlstring(dbpass));         con->setschema(sql::sqlstring(dbname));         isconnected = true;          std::cout<<"database connection successul."<<std::endl;      } catch(sql::sqlexception &e) {         manageexception(e);         isconnected = false;          return;     } }  bool dbmanager::validcredentials(const char* username, const char* password) {     bool cred = false;      try {         pstmt = con->preparestatement("select * account account_name=? limit 1"); // smart use of indexing         pstmt->setstring(1, username);         res = pstmt->executequery();          while(res->next())         {             if (res->getstring("password") == password)             {                 cred = true;             }         }     }     catch(sql::sqlexception &e) {         manageexception(e);         return false;     }      return cred; } 

basically, compiles without problem, connects without problem, executes queries without problem, second try retrieve data breakpoint exception thrown in file "xutils.cpp". have no idea i'm doing wrong. i'm using debug libraries while compiling debug. hmm libmysql.dll should release since extracted server bundle, don't seem find source compile own.

i have no idea why crashes , burn :/

ps: don't mind no hashing of password, proof of concept me in way of ... getting work first, securing :u

ps: have boost libraries compiled , ready in project, if :u

edit: main function

bool serverrunning = true; int main(int argc, char** argv) {     #ifdef _win32         std::string title = text("window title change");         setconsoletitle(title.c_str());     #endif;      std::cout<<"loading configuration file..."<<std::endl<<std::endl;      std::string path = boost::filesystem::path(boost::filesystem::current_path()).string();     path += "\\config.ini";      iniparser* config = new iniparser(path.c_str()); //minini      // sockets data     std::string listenip = config->getstring("network", "listenip", "127.0.0.1");     unsigned short listenport = config->getint("network", "listenport", 5000);      // database data     std::string dbhost = config->getstring("database", "host", "localhost");     std::string dbuser = config->getstring("database", "user", "root");     std::string dbpass = config->getstring("database", "password", "");     std::string dbname = config->getstring("database", "database", "authserv");     unsigned short dbport = config->getint("database", "post", 1000);      // general settings     int sessiontimeout = config->getint("settings", "sessiontimeout", 10);     int maxclients = config->getint("settings", "maxclients", 10);     int servertimeout = config->getint("settings", "gameservertimeout", 1);       // begin initialization      dbmanager::instance()->connect(dbhost.c_str(), dbport, dbuser.c_str(), dbpass.c_str(), dbname.c_str());      bool loginsuccess = dbmanager::instance()->validcredentials("username", "password");      char c;     while (serverrunning)     {         std::cin>>c;          if (c == 'q')         {             serverrunning = false;         }     }      return 0; } 

assuming password field defined varchar in database, cannot use getstring() retrieve it. must instead use blob function, getblob().

this how while loop look:

while(res->next()) {     std::istream * retrievedpassword_stream = res->getblob("password");     if (retrievedpassword_stream)     {         char pws[password_length+1]; // password_length defined elsewhere; or use other functions retrieve         retrievedpassword_stream->getline(pws, password_length);         std::string retrievedpassword(pws); // also, should handle case password length > password_length         if (retrievedpassword == std::string(password))         {             cred = true;         }     } } 

side comments: note there other issues code.

  • the statement handle must deleted, should delete pstmt; @ appropriate place in validcredentials() function (rather in destructor). (but, why use prepared statement in case anyways? better initialize prepared statement in constructor (or somewhere else outside function query called), delete in destructor or elsewhere, if do use prepared statement. instead of prepared statement, though, note prepared statements useful high-use , high-cpu intensive queries, using password validation might not important here (you execute regular query, instead of prepared statement).)
  • likewise, resultset needs deleted (delete res) @ end of try block, rather in destructor.
  • be sure check null before using pstmt, res, or con.
  • stmt appears unused , should not deleted.

Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -