【问题标题】:sqlite global variable bugsqlite 全局变量错误
【发布时间】:2011-03-02 11:52:19
【问题描述】:

我有一个名为mob 的全局变量。当我第一次打印它时,它是我所期望的:“狼”。但是当我在main 的末尾再次打印它时,它看起来像'до'。我调试了很多这段代码,mob 是全局的,所以我不明白如何更改它。如有必要,我可以将 cmets 添加到部分代码中。

我正在使用 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

【问题讨论】:

  • 顺便说一下,“全局”是“坏的,因为它可以从任何地方更改”的定义。
  • 您可以在 Wiki Wiki Web 上阅读更多关于为什么 globals are bad 的信息。关于发布代码,请参阅Short, Self Contained, Correct (Compilable), Example(认为发布的示例看起来相当小)。
  • @outis 我知道,这只是一个测试程序。

标签: c++ sql sqlite


【解决方案1】:

Mob::_name 是一个原始指针,您将其设置为由 SQLite 拥有和管理的字符串。当您尝试再次输出字符串时,SQLite 已经重用了该内存,因此您的程序会遇到未定义的行为,并且您会看到垃圾打印。

您应该对字符串进行深度复制 - 最好使用 std::string 来存储它。

【讨论】:

    猜你喜欢
    • 2021-10-13
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多