2011-03-02 36 views
3

我有一個名爲mob的全局變量。當我第一次打印它時,它就是我所期望的:'狼'。但是,當我在main的末尾再次打印時,它看起來像'до'。我調試了很多代碼,mob是全球性的,所以我不明白它是如何改變的。如有必要,我可以在部分代碼中添加註釋。sqlite全局變量bug

我正在使用sqlite3,Visual Studio 2010和Win 7 x64。

#include "stdafx.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 

#include "sqlite3.h" 
struct Mob { 
    Mob():_name(0),_lvl(0),_loot(0){} 

unsigned const char* _name; 
unsigned const char* _lvl; 
unsigned const char* _loot; 

}mob; 

void main() 
{ 
    sqlite3 *db; 
    sqlite3_stmt * pStmt; 
    int i, j, coln, rc; 
    int b = 1; 

    char *sql[] = { 
    "CREATE TABLE tbl (name TEXT,lvl INTEGER,loot TEXT);", 
    "INSERT INTO tbl VALUES('Wolf',5,'Meat');", 
    "SELECT * FROM tbl;" 
    }; 

    if (sqlite3_open("exam2.db", &db)) 
    { 
     printf("Error: %s\n", sqlite3_errmsg(db)); 
     sqlite3_close(db); 
     system("pause"); 
     exit(1); 
    } 

    for (i=0; i<sizeof(sql)/sizeof(sql[0]); i++) 
    { 

     if (sqlite3_prepare(db, sql[i], -1, &pStmt, NULL)) 
     { 
      printf("Error: %s\n", sqlite3_errmsg(db)); 
      sqlite3_finalize(pStmt); 
      sqlite3_close(db); 
      system("pause"); 
      exit(1); 
     } 

     coln = sqlite3_column_count(pStmt); 


     while((rc = sqlite3_step(pStmt)) == SQLITE_ROW) 
     { 

      coln = sqlite3_data_count(pStmt); 

      mob._name=sqlite3_column_text(pStmt, 0); 
      std::cout<<mob._name<<std::endl; //1 

     } 

     if (rc != SQLITE_DONE) printf("Error: %s\n", 
       sqlite3_errmsg(db)); 

     sqlite3_finalize(pStmt); 
    } 


    std::cout<<mob._name<<std::endl; //2 

    sqlite3_close(db); 
    system("pause"); 
} //end main 
+0

順便說一句,「全球」是「壞,因爲它可以從任何地方改變」的定義。 – Puppy 2011-03-02 12:04:39

+0

你可以在Wiki Wiki上閱讀更多關於[globals are bad]的原因(http://c2.com/cgi/wiki?GlobalVariablesAreBad)。在發佈代碼時,請參見[簡短,自包含,正確(可編譯),示例](http://sscce.org/)(認爲發佈的示例看起來相當簡單)。 – outis 2011-03-02 12:08:42

+0

@outis我知道,這只是一個測試程序。 – Stals 2011-03-02 12:14:24

回答

5

Mob::_name是一個原始指針,並將其設置爲由SQLite擁有和管理的字符串。當你試圖再次輸出字符串時,SQLite已經重用了這個內存,所以你的程序運行到未定義的行爲,並且你看到了垃圾打印。

您應該深度複製字符串 - 最好使用std::string來存儲它。