我正在尝试制作一个测试程序,以查看我从一个结构中获取和存储来自SQLite3数据库的数据的想法是否有效但我遇到了代码的一些主要问题。在调试时我会继续遇到标题中的错误。以下是错误窗口的全文:
Debug Assertion失败!
文件:include \ xstring 行:929
表达式:无效的空指针
有关程序如何导致断言的信息 失败,请参阅关于断言的Visual C ++文档。
这是代码,我将用箭头指出问题所在的行(< - ;额外的帮助见转换的情况2):
#include <iostream>
#include "data_placeholder.h"
#include "sqlite3.h"
#include <vector>
#include <conio.h>
#include <string>
#include <sstream>
using namespace std;
void openDB(sqlite3* dBase, int iID, string table, string operation, sqlite3_stmt* statement, vector<mission>& mission_1);
void createStatement(int iID, string table, string operation, sqlite3_stmt* statement, sqlite3* dBase, vector<mission>& mission_1);
void getMResults(string sqlStr, sqlite3_stmt* statement, sqlite3* dBase, vector<mission>& mission_1);
void returnMResult(vector<mission> mResults, vector<mission>& mission_1);
int main()
{
//Define Variables
vector<mission> mission_1;
sqlite3 *dBase;
sqlite3_stmt *statement;
int pInput;
mission_1.push_back(mission());
cout << "Input a number between 1 and 3" << endl;
cout << ">";
cin >> pInput;
cout << endl;
cout << endl;
openDB(dBase, pInput, "Mission_Data", "select from", statement, mission_1);
cout << mission_1.at(0).mName << ", " << mission_1.at(0).mDesc << ", " << mission_1.at(0).mCBELevel << ", " << mission_1.at(0).mSCReq << ", " << mission_1.at(0).mMWReq << ", " << mission_1.at(0).mTLimit << ", " << mission_1.at(0).mDifficulty << ", " << mission_1.at(0).mSector << ", " << mission_1.at(0).mSystem << ", " << mission_1.at(0).mTName << ", " << mission_1.at(0).mTSClass << ", " << mission_1.at(0).mBounty << ", " << mission_1.at(0).mXarn << ", " << mission_1.at(0).mRubies << ", " << mission_1.at(0).mDiamonds << ", " << mission_1.at(0).mDraconic << ", " << mission_1.at(0).mLithium << ", " << mission_1.at(0).mPlatinum << ", " << mission_1.at(0).mUranium << ", " << mission_1.at(0).mPlutonium << ", " << mission_1.at(0).mNWaste << ", " << mission_1.at(0).mCEXP << ", " << mission_1.at(0).mItem << ", " << mission_1.at(0).mType << ", " << endl;
_getch();
}
void openDB(sqlite3* dBase, int iID, string table, string operation, sqlite3_stmt* statement, vector<mission>& mission_1)
{
sqlite3_open("scDatabase.sqlite",&dBase);
createStatement(iID, table, operation, statement, dBase, mission_1);
}
void createStatement(int iID, string table, string operation, sqlite3_stmt* statement, sqlite3* dBase, vector<mission>& mission_1)
{
stringstream ss;
ss << iID;
string sID(ss.str());
string sqlStr = "Select * From " + table + " Where ID = " + sID;
getMResults(sqlStr, statement, dBase, mission_1);
}
void getMResults(string sqlStr, sqlite3_stmt* statement, sqlite3* dBase, vector<mission>& mission_1)
{
vector<mission> mResults;
mResults.push_back(mission());
if (sqlite3_prepare_v2(dBase, sqlStr.c_str(), sqlStr.size(), &statement, 0) == SQLITE_OK)
{
int cols;
int i;
cols = sqlite3_column_count(statement);
for (i =01; i <= cols; i++)
{
switch(i)
{
case 2:
mResults.at(0).mName = string((char*)sqlite3_column_text(statement,i)); //<-- Here is the line the assert fail happens
break;
/*
case 3:
mResults.at(0).mDesc = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 4:
mResults.at(0).mCBELevel = sqlite3_column_int(statement,i);
break;
case 5:
mResults.at(0).mSCReq = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 6:
mResults.at(0).mMWReq = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 7:
mResults.at(0).mTLimit = sqlite3_column_int(statement,i);
break;
case 8:
mResults.at(0).mDifficulty = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 9:
mResults.at(0).mSector = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 10:
mResults.at(0).mSystem = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 11:
mResults.at(0).mTName = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 12:
mResults.at(0).mTSClass = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
case 13:
mResults.at(0).mBounty = sqlite3_column_int(statement,i);
break;
case 14:
mResults.at(0).mXarn = sqlite3_column_int(statement,i);
break;
case 15:
mResults.at(0).mRubies = sqlite3_column_int(statement,i);
break;
case 16:
mResults.at(0).mDiamonds = sqlite3_column_int(statement,i);
break;
case 17:
mResults.at(0).mDraconic = sqlite3_column_int(statement,i);
break;
case 18:
mResults.at(0).mLithium = sqlite3_column_int(statement,i);
break;
case 19:
mResults.at(0).mPlatinum = sqlite3_column_int(statement,i);
break;
case 20:
mResults.at(0).mNWaste = sqlite3_column_int(statement,i);
break;
case 21:
mResults.at(0).mCEXP = sqlite3_column_int(statement,i);
break;
case 22:
mResults.at(0).mItem = sqlite3_column_int(statement,i);
break;
case 23:
mResults.at(0).mType = string(reinterpret_cast<const char*>(sqlite3_column_text(statement,i)));
break;
*/
default:
break;
}
}
}
else
{
cout << "something is wrong" << endl;
}
returnMResult(mResults, mission_1);
}
void returnMResult(vector<mission>mResults, vector<mission>& mission_1)
{
mission_1.at(0) = mResults.at(0);
}
当代码在第一次迭代中通过for循环到达此行时,会立即发生错误。没有编译器错误,我也尝试将前三个函数折叠成一个函数,以防数据库和语句指针没有正确传递;同样的问题。
编辑2:我已经缩小了问题所在。它与我的结构矢量有关。我从我设置为mResults.at(0).mName的链接中取出了数据库查询,然后为const unsigned char添加了一个转换为字符串,但断言失败仍然发生。
编辑3:在查看我在今年早些时候做过的一些代码后,我已经弄清楚发生了什么,至少对于SQLite查询。您必须调用步骤才能实际执行查询。由于我没有这样做,指针始终返回为无效,因为没有加载行,因此没有要查询的列。我的载体没什么问题。
答案 0 :(得分:1)
有问题的一行:
sqlite3_column_text(statement,i)
将返回未定义的值,因为当i等于size时,它将超出范围。
sqlite3_column_text函数iCol参数是C风格索引,以零开头,同时尝试获取列索引sql-style起始1.修复循环为:
for (i = 0; i < cols; i++)
答案 1 :(得分:1)
我弄明白了这个问题。我回顾了一些我在6月左右制作的代码,我已经开始将它与我上面发布的代码进行比较。在存在差异的地方,我将代码复制到了新的测试中,我终于让它工作了。
问题是我没有调用sqlite3_step,因此没有查询数据库。这导致没有加载行,因此没有要查询的列,因此sqlite3_column_text返回了无效指针。然而,Iuri还有一个观点,即我正在以一种方式进行迭代,如果我得到的错误是固定的,那么它将开始超出界限,我还没有能够让代码走得那么远一点先发制人的调试。
我还添加了一些基本防御性编码的检查,以便测试应用程序失败,如果没有加载行或指针无效,那么运行时不会启动程序。