質問

I am attempting to make a test program to see if an idea I had for getting and storing data from an SQLite3 database in a struct would work but I am running into some major problems with the code. While debugging I keep running into the error in the title. Here is the full text of the error window:

Debug Assertion Failed!

File: include\xstring Line: 929

Expression: invalid null pointer

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

And here is the code, I will indicate which line the problem is with an arrow (<--; extra help see case 2 of the switch):

#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);
}

The error occurs instantly when the code hits this line on the first iteration through the for loop. There are no compiler errors and I have also tried collapsing the first three functions into one function in case the database and statement pointers were not being passed correctly; same problem.

Edit 2: I have whittled down where the problem is. It has to do with my vector of structs. I took the database query out of the link where I set to mResults.at(0).mName and then added a cast for the const unsigned char to string but the assert failure still happens.

Edit 3: After looking at some code I had done earlier in the the year I have figure out what was going on, at least for the SQLite query. You have to called step in order for the query to actually be carried out. Since I had not done so the pointer was always returning as invalid since there was no row loaded and thus no columns to query. Nothing wrong with my vector.

役に立ちましたか?

解決 2

I figured out the problem. I looked back at some code I had made around June that I had working and started comparing it to the code I posted above. In the places where there were differences I copied the code over to the new test and I finally got it to work.

The problem was that I was not calling sqlite3_step so the database was not being queried. This lead to no row being loaded and so no columns to query, thus an invalid pointer returned by the sqlite3_column_text. However Iuri also had a point in that I was iterating through in a way that, if the error I was getting was fixed, would have started going out of bounds, I had not been able to get the code to go that far yet so a bit of preemptive debugging.

I also added checks in for some basic defensive coding so that the test application fails save if there is either not a row loaded or an invalid pointer so that the runtime does not kick the program out.

他のヒント

problematic line:

sqlite3_column_text(statement,i)

will return undefined value, because when i is equal to size, it will go out of bounds.

sqlite3_column_text function iCol parameter is C-style index, that starts with zero, while you try to get column index sql-style starting 1. Fix the loop to be:

for (i = 0; i < cols; i++)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top