我遇到的情况是我们与sqlite3的连接没有通过。这是我的队友代码,但他离开了团队,现在我正在尝试解决代码中的问题,但我很丢失。程序编译,我只能在QtCreator中找到调试工具的问题位置。调试器工具将我带到sqlite_prepare_v2来解决问题。
调试器输出是:(我发布这个因为它可能有用)
nByte 84 size_t
query "SELECT username,password FROM users WHERE username='dilsizk' AND password='12345678'" std::string
return_matrix <not accessible> std::vector<std::vector<std::string>>
return_value 32745 int
this @0x7fe90ab23f5f DBHandler
columns_ -1282717696 int
db_connection_ 0x740000800003f7da sqlite3 * *
log @0x7fe90ab23f5f Log
count -1064971727 int
query_ 0x401f0fc35bd08908 sqlite3_stmt * *
return_matrix_ 0xc748eb7501046e83 std::vector<std::vector<std::string>> *
unusedSQL "12345678" char *
该方法的代码是:
//query must be nul-terminated (ending in \0)
//if an error code is returned, method returns what it has processed to that point
std::vector<std::vector<std::string>>* DBHandler::runQuery(std::string query) {
//get byte size of query
size_t nByte = std::strlen(query.c_str());
//log
log << "DBHandler: Query size is " + std::to_string((int)nByte) +" bytes";
//make junk variable for potential unused sql
const char **unusedSQL;
//prepare the statement
sqlite3_prepare_v2(*db_connection_,query.c_str(),(int)nByte,query_,unusedSQL);
//log
log << "DBHandler: Query formatted into prepared statement";
//perform first step, grab return value
int return_value = sqlite3_step(*query_);
//log
log << "DBHandler: First evaluation step completed";
//check if done, and if it is because of an error or that there is only 1 row
if(return_value != SQLITE_ROW) {
//log
log << "DBHandler: Query returns only 1 row";
if(return_value != SQLITE_DONE) {
//log
log << "DBHandler: Error handling query, code 1";
return (new std::vector<std::vector<std::string>>);
}
}
该方法还有更多内容但我并不想发布整个内容,因为程序无法进入后面的步骤
sqlite3_prepare_v2(*db_connection_,query.c_str(),(int)nByte,query_,unusedSQL);
另外,让我为变量提供dbhandler.h的头文件。
#include <algorithm>
#include <sqlite3.h>
#include <vector>
#include <cstring>
#include "log.h"
#include <iostream>
/* Class to handle interaction with the local test database in the /db_tools directory. Run ./newDB.sh in that directory prior to use. */
class DBHandler {
public:
/* Constructor to create DBHandler object. */
/*!
* This object should ALWAYS be destroyed by its destructor when use is done. The constructor only opens a connection to the local database.
*/
DBHandler();
/* Destructor to prevent memory leaks from this object. */
/*!
* Important that this is called, as it is otherwise vulnerable to causing multiple memory leaks.
*/
~DBHandler();
/* Runs a query to the database and returns the output in a formatted vector. */
/*!
* This method formats the query, passed as a string, into a prepared statement to be processed.
* \param query The query to the database. Must be nul-terminated (ending in \0) with no whitespace between the end of the query and the zero-terminator.
* \return Returns a vector, where each index holds a vector per column, whose 0 index is the column name and all following indices are entries in order of their row.
*/
std::vector<std::vector<std::string>>* runQuery(std::string query);
private:
Log log;
sqlite3** db_connection_; /** Database connection object. **/
sqlite3_stmt** query_; /** Prepared statement object. **/
int columns_; /** Number of columns in the prepared statement after 1 step. **/
std::vector<std::vector<std::string>>* return_matrix_; /** Pointer to the matrix containing the evaluation of the prepared statement. **/
/* Fills the return matrix with the names of the columns in the prepared statement. */
void fillColName();
/* Fills each column vector in the return matrix with the entries from the most recent step of the prepared statement. */
void fillRow();
};
我很抱歉很多文字,但我认为这些输出在尝试解决问题时很有用。
如果我还能提供其他任何内容,或者我的问题遗失了,请告诉我。我是一个相当新的网站。只是试图能够提出格式正确的问题。
感谢。
答案 0 :(得分:0)
根据documentation,sqlite_prepare_v2
的最后一个参数是接收SQL语句其余部分的指针的位置(因为prepare只编译查询中的第一个sql语句)。 / p>
您的代码将未初始化的变量作为该参数传递,因此当sqlite_prepare_v2
尝试更改指针的值时,它会覆盖一些随机内存。
使用类似的东西:
const char *unusedSQL = NULL;
//prepare the statement
sqlite3_prepare_v2(*db_connection_,query.c_str(),(int)nByte,query_,&unusedSQL);
sqlite3_prepare_v2
的第四个参数应该是指向将接收已编译语句的变量的指针,您的代码正在传递_query
,这是您班级的成员变量,但是您还没有& #39; t显示了它是如何初始化的。我怀疑这与unusedSQL
具有相同的问题。
您应该将声明更改为
sqlite3_stmt* query_
并传递指向query_
参数的指针:
const char *unusedSQL = NULL;
query_ = NULL;
//prepare the statement
sqlite3_prepare_v2(*db_connection_,query.c_str(),(int)nByte, &query_, &unusedSQL);
另请注意:sqlite3_prepare_v2
有一个返回值 - 您应该检查它是否一切正常。