c++ - 这是 MSVC 2010 中的错误还是我做错了什么?

标签 c++ visual-studio-2010 c++11

考虑以下代码片段:

在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 )
            {

char *result_query = sqlite3_expanded_sql( stmt ); res = sqlite3_step(stmt);

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

我必须在第一次调用“to_bytes()”后做些什么吗?或者我只需要升级编译器?

最佳答案

不,你做错了什么。

我现在实际上不知道 to_bytes 返回什么,但我假设它是基于 std::basic_string 的类型,所以 std: :string 和家庭。

to_bytes 返回一个临时对象给那个字符串实例,所以当你调用 c_str() 时,你得到一个指向字符串第一个字符的指针,它不再语句完成后存在。你基本上有未定义的行为,因为 name 是一个悬空指针并且你试图输出它。

你必须分配内存并将字符串复制到其中,或者只使用 std::string,其中不会出现类型的问题。

之所以调用sqlite3_prepare_v2成功是因为to_bytes返回的字符串仍然存在。当语句结束时字符串被销毁,所以当 res 被赋值时 sqlite3_prepare_v2 的返回值。之前没有,因此调用成功,因为传递了指向字符串的有效指针。

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

关于c++ - 这是 MSVC 2010 中的错误还是我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41372965/

相关文章:

c++ - Lambda 变量捕获

c++ - 将本地字符串参数作为对 const 的引用传递到 constexpr 函数中?为什么这是合法的?

android - 使用 Mono for Android 在 Microsoft Visual Studio 2010 中打包 .apk

visual-studio-2010 - 在Visual Studio 2012中的滚动条上没有更多的红点

c++ - 使用 Boost Python 有条件地添加模块

c++ - 有没有办法缩短长 switch() 语句?

c# - 文件具有与 list 中指定的不同的计算哈希值

c++ - const_forward 在 C++ 的可选实现中做了什么?

c++ - std::array 的嵌套聚合初始化

c++ - main() 之前运行的是什么?