문제

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