我正在尝试使用libmysql++
API查询数据库,到目前为止,我能够成功运行一些查询。 (某些背后的原因将在稍后解释)
所以一切正常,但只要我尝试关闭连接并退出程序,就会出现Segmentation fault (core dumped)
,如下所示:
shell> g++ -o test testCDB.cpp -L/usr/include/mysql -lmysqlclient -I/usr/include/mysql
testCDB.cpp: In function ‘int main(int, char**)’:
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
StudentManager manager1("localhost", "root", "ikilledkennedy.", "testDB");
^
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
testCDB.cpp:122:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
shell> ./test
Successfully connected to the database.
Enter your query: SHOW DATABASES;
[information_schema]
[mysql]
[performance_schema]
[sys]
[testDB]
Do you wish to continue?(Y:1/N:0) : 1
Enter your query: SHOW TABLES;
[Student]
Do you wish to continue?(Y:1/N:0) : 0
Segmentation fault (core dumped)
shell>
导致此问题的原因以及我采取了哪些措施来解决此问题?
来到一些查询部分 - 某些查询在提供给数据库(例如Segmentation fault
)时也会以INSERT
退出,我觉得这是因为这些查询不会生成结果集,当我尝试在displayTable()
中获取行或者在performQuery(char *)
中释放结果集时,会遇到NULL
值。我是否正确地思考这个问题还是有其他根本原因?
代码如下:
#include <iostream>
#include <string>
#include <mysql.h>
#include <limits>
using namespace std;
class StudentManager
{
private:
char *host;
char *user;
char *password;
char *database;
MYSQL *connection;
MYSQL_RES *result;
void init()
{
connection = mysql_init(NULL);
if(!mysql_real_connect(connection, host, user, password, database, 0, NULL, 0))
{
cout << "Cannot connect to the database.\n"
<< "Please make sure you have entered the details correctly and try again."
<< endl;
}
else
{
cout << "Successfully connected to the database.\n"
<< endl;
}
}
void displayTable()
{
MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;
num_fields = mysql_num_fields(result);
cout << endl;
while((row = mysql_fetch_row(result)))
{
for(i = 0; i < num_fields; i++)
{
cout << "[" << ( row[i] ? row[i] : "NULL" ) << "]";
}
cout << endl;
}
cout << endl;
}
public:
StudentManager(char *host, char *user, char *password, char *database)
{
this->host = host;
this->user = user;
this->password = password;
this->database = database;
init();
}
void performQuery(char *query)
{
if(mysql_query(connection, query))
{
cout << "Query error: "
<< mysql_error(connection)
<< endl;
return;
}
result = mysql_use_result(connection);
displayTable();
mysql_free_result(result);
}
void disconnect()
{
cout << "Closing connection...";
mysql_close(connection);
cout << "Connection successfully closed.";
}
};
int main(int argc, char *argv[])
{
StudentManager manager1("localhost", "foo", "bar", "testDB");
int choice = 1;
char *query;
while(1)
{
cout << "Enter your query: ";
cin.getline(query, 256);
manager1.performQuery(query);
cout << "Do you wish to continue?(Y:1/N:0) : ";
cin >> choice;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if(choice < 1)
{
manager1.disconnect();
break;
}
}
return 0;
}
答案 0 :(得分:0)
你在这里使用未初始化的指针:
char *query;
while(1)
{
cout << "Enter your query: ";
cin.getline(query, 256);
query
变量未初始化,并指向某个随机内存位置。最有可能在堆栈段的某个地方。使用getline
写入该位置时,会损坏堆栈。这会导致分段错误。
由于相关代码似乎没有性能关键,我建议重写这样的代码:
std::string line;
while (cin.good())
{
cout << "Enter your query: ";
std::getline(cin, line);
PS我认为代码还存在其他一些问题,但由于问题是关于分段错误,我会把答案集中在一起。
答案 1 :(得分:0)
看起来内存在早期损坏,在这里:
char *query; // <-- uninitialized buffer
while(1)
{
cout << "Enter your query: ";
cin.getline(query, 256);
getline
从流中读取数据并将其存储到缓冲区中。适当长度的缓冲区应由您分配。要修复它,请使用:
char query[256];
某些查询在输入数据库时也会出现Segmentation错误(如INSERT),我觉得这些查询不会生成结果集
INSERT
查询不会生成结果集,因此根据文档mysql_fetch_row(result)
返回NULL
。这是正确的行为,而不是Segmentation fault
的原因。