2016-12-29 146 views
1

考虑下面的代码片断:这是MSVC 2010中的错误还是我做错了什么?

在database_sqlite.h:

class __declspec(dllexport) SQLiteDatabase : public Database 
{ 
    virtual void GetTableProperties(DatabaseTable *table, std::vector<std::wstring> &errorMsg); 
protected: 
    struct SQLiteImpl; 
}; 

struct SQLiteDatabase::SQLiteImpl 
{ 
    std::wstring m_catalog; 
    std::wstring_convert<std::codecvt_utf8<wchar_t> > m_myconv; 
}; 

在database_sqlite.cpp:

void SQLiteDatabase::GetTableProperties(DatabaseTable *table, std::vector<std::wstring> &errorMsg) 
{ 
    sqlite3_stmt *stmt = NULL; 
    std::wstring errorMessage; 
    int result; 
    std::wstring query = L"SELECT * FROM \"sys.abcattbl\" WHERE \"abt_tnam\" = ? AND \"abt_ownr\" = ?;"; 
    const unsigned char *dataFontName, *headingFontName, *labelFontName; 
    int res = sqlite3_prepare_v2(m_db, sqlite_pimpl->m_myconv.to_bytes(query.c_str()).c_str(), (int) query.length(), &stmt, 0); 
    if(res == SQLITE_OK) 
    { 
const char *name = sqlite_pimpl->m_myconv.to_bytes(table->GetTableName().c_str()).c_str(); // I used this line for debugging purposes 
    res = sqlite3_bind_text(stmt, 1, sqlite_pimpl->m_myconv.to_bytes(table->GetTableName().c_str()).c_str(), -1, SQLITE_STATIC); 
    if(res == SQLITE_OK) 
    { 
     res = sqlite3_bind_text(stmt, 2, sqlite_pimpl->m_myconv.to_bytes(table->GetSchemaName().c_str()).c_str(), -1, SQLITE_STATIC); 
     if(res == SQLITE_OK) 
     { 
      while(true) 
      { 

字符* result_query = sqlite3_expanded_sql(语句); res = sqlite3_step(stmt);

这里* result_query contains =“SELECT * FROM”sys.abcattbl“WHERE”abt_tnam“=''AND”abt_ownr“='';” 我正在使用MSVC2010,令我惊讶的是,“* name”包含空字符串。第一次调用“to_bytes()”成功,因为我可以检查将要使用的查询。

第一次打电话给“to_bytes()”后我需要做些什么吗?或者我只需升级编译器?

回答

0

不,你做错了什么。

我实际上并不什么现在to_bytes回报,但我认为它是一个std::basic_string型基极,使std::string和家人。

to_bytes返回一个临时对象到字符串实例,所以当你打电话c_str(),你得到一个指针,指向陈述结束后不再存在的字符串的第一个字符。你基本上有未定义的行为,因为name是一个悬挂指针,你试图输出它。

你必须分配内存和字符串复制到它,或只是使用std::string,也不会发生类型的问题在哪里。

您拨打sqlite3_prepare_v2成功的原因是因为to_bytes返回的字符串仍然存在。当语句结束时字符串被破坏,所以当res被分配了返回值sqlite3_prepare_v2。之前没有,因此调用成功,因为传递了一个有效的字符串指针。

尽管如此,请升级您的编译器。

+0

但是如何调用“sqlite3_prepare_v2()”成功?另外,请检查我的编辑 - 我添加更多的代码。谢谢。 – Igor

+0

@Igor请看我的编辑。 – Rakete1111

+1

现在一切正常。将“sqlite3_bind_text()”最后一个参数更改为“SQLITE_TRANSIENT”修复了问题。出于某种原因,我很确定我需要SQLITE_STATIC。再次和新年快乐。 – Igor

相关问题