2013-10-05 60 views
1

我試圖做一個測試程序,看看我是否有一個想法來獲取和存儲來自SQLite3數據庫的數據在結構中的數據將工作,但我遇到了代碼的一些主要問題。在調試過程中,我不斷遇到標題中的錯誤。以下是錯誤窗口的全文:調試斷言失敗:空指針無效

調試斷言失敗!

文件:包括\ 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查詢。您必須調用步驟以便查詢實際執行。由於我沒有這樣做,指針總是返回無效,因爲沒有加載行,因此沒有列進行查詢。我的矢量沒有錯。

回答

1

我想通了這個問題。我回頭看了一下我在六月份做的一些代碼,我已經開始工作,並開始將它與上面發佈的代碼進行比較。在存在差異的地方,我將代碼複製到新測試中,並最終使其工作。

問題是我沒有調用sqlite3_step,因此數據庫沒有被查詢。這導致沒有行被加載,因此沒有列進行查詢,因此sqlite3_column_text返回的無效指針。然而,Iuri也有一個觀點,我正在迭代的方式是,如果我得到的錯誤得到解決,就會開始走出界限,我還沒有能夠獲得代碼去那麼遠,所以一些搶先調試。

我還爲一些基本的防禦性編碼添加了檢查,以便測試應用程序失敗時保存是否存在未裝載行或無效指針,以便運行時不會將程序踢出。

1

問題的行:

sqlite3_column_text(statement,i) 

將返回未定義的值,因爲當我等於大小,它會出界。

sqlite3_column_text功能ICOL參數是C-風格指數,與零開始,而你試圖讓列索引SQL風格開始1.修復循環是:

for (i = 0; i < cols; i++) 
+0

進行了更改,但當它遇到該行時仍然出錯。爲了進一步澄清,程序在第一次迭代時遇到第二種情況就會出錯。將更新問題。 – Geowil