So I'm trying to build a class that connects to a mysql database and I want to connect in the constructor and catch exceptions to handle them and not construct the class. For reasons I won't go into I need it to work this way. I have found the error in the destructor of SQLConnection.cpp when it tries to delete a pointer. This pointer is instantiated from a MySQL connector library function and every tutorial and example I've seen has it deleted at the end. It doesn't seem right to me, but I couldn't find the documentation on the function to see why this delete was there. Also when I did delete this same pointer just running some tests in main it was fine (no seg fault).
Here is the important code so far
SQLConnection.h
#ifndef SQLCONNECTION_H
#define SQLCONNECTION_H
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
class SQLConnection{
private:
sql::Driver *driver;
const std::string IP;
const std::string user;
const std::string password;
void connect();
public:
sql::Connection *con;
SQLConnection();
SQLConnection(std::string inIP, std::string inUser, std::string inPassword);
~SQLConnection();
};
#endif
SQLConnection.cpp (the delete in the destructor causes the seg fault. When taken out it goes away. I'll show why I'm concerned with taking it out all together after this
#include "SQLConnection.h"
SQLConnection::SQLConnection() = default;
SQLConnection::SQLConnection(const std::string inIP, const std::string inUser, const std::string inPassword)
: IP(inIP), user(inUser), password(inPassword)
{
try
{
connect();
}
catch(...)
{
throw;
}
}
SQLConnection::~SQLConnection(){
if(con != nullptr){
delete con; //CAUSES SEG FAULT, when taken out program runs fine
}
}
void SQLConnection::connect(){
try{
driver = get_driver_instance();
con = driver->connect(IP, user, password);
}
catch (sql::SQLException &e) {
std::cout << "# ERR: SQLException in " << __FILE__;
std::cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << '\n';
std::cout << "# ERR: " << e.what() << '\n';
std::cout << "# ERR: MySQL error code: " << e.getErrorCode() << '\n';
}
if(con)
{
std::cout<<"Connected!" << "\n";
}
}
main.cpp
const std::string ip = "tcp://127.0.0.1:3306";
const std::string user = "IncorrectUser";
const std::string password = "IncorrectPass";
SQLConnection con1(ip, user, password);
std::cout << "still going" << '\n';
when this runs with incorrect login credentials it output
4 line of exceptions from catch block in connect
connected!
still going
segmentation fault (core dumped)
with correct credentials everything works fine
main.cpp without classes to test connection works fine
try{
driver = get_driver_instance();
con = driver->connect(IP, user, password);
}
catch(sql::SQLException &e){
std::cout << e.what() << '\n';
if(con){
std::cout << "connected!" << '\n';
}
delete con;
so I guess my main question is why is it saying connected if the constructor threw an exception shouldn't the class have never come into "existence". thus it shouldn't be saying connected and call it's destructor at the end of main causing the seg fault? Also If I need to use function level try catch in the constructor to fix this can someone give me a tip on how to call a member function from an initilization list. When I tried that before I got a compiler error saying
member field connect() does not exist