Sqlite3 добавляется мусор вместо строк

251
26 декабря 2017, 17:30

Не получается корректно вставить строки в таблицу с использованием шаблонов, пробую так:

template<typename ...Types>
void bind(sqlite3_stmt *stmt, Types ...arg)
{
    std::string arr[] = { arg... };
    size_t i = 1;
    for (auto &e: arr) {
        sqlite3_bind_text(stmt, i, e.c_str(), -1, 0 );
        i++;
    }
}
template<typename ...Types>
void exec(std::string sqlCmd, Types ...arg)
{
    sqlite3 *handle;
    sqlite3_stmt *stmt;
    sqlite3_open("test.db", &handle);
    sqlite3_prepare_v2(handle, sqlCmd.c_str(), -1, &stmt, 0);
    bind(stmt, arg...);
    sqlite3_step(stmt);
}
int main()
{
    exec("CREATE TABLE test_table (first_col TEXT, second_col TEXT, third_col TEXT);");
    exec("INSERT INTO test_table (first_col, second_col, third_col) VALUES ( ? , ? , ? )",
        "val_1",
        "val_2",
        "val_3");
}

После выполнения в базу строки добавляются в таком виде(какой-то мусор):

first_col   second_col  third_col 
----------  ----------  ----------
��                      val_3    
�z�x�                     val_3 
�����                      val_3 

Если не выносить код в отдельную функцию bind, все работает нормально. Почему? Я не правильно передаю шаблон переменной длины?
Также если внутри bind объявить const char* arr[]вместо std::string arr[], то все работает нормально.

Answer 1

У вас локальная переменная в функции bind уничтожается после выхода из функции:

std::string arr[] = { arg... };

Могу посоветовать переписать так:

void bind(sqlite3_stmt *stmt, std::vector<std::string>& arr) // НЕ-const, чтобы временный объект не передать случайно
{
    size_t i = 1;
    for (auto &e: arr) {
        sqlite3_bind_text(stmt, i, e.c_str(), -1, 0 );
        i++;
    }
}
template<typename ...Types>
void exec(std::string sqlCmd, Types ...arg)
{
    sqlite3 *handle;
    sqlite3_stmt *stmt;
    sqlite3_open("test.db", &handle);
    sqlite3_prepare_v2(handle, sqlCmd.c_str(), -1, &stmt, 0);
    std::vector<std::string> arr{ arg... };
    bind(stmt, arr);
    sqlite3_step(stmt);
}
READ ALSO
Ошибка при qsort по вектору структур

Ошибка при qsort по вектору структур

Добрый деньИмеется структура:

269
OSM отображение карты C++

OSM отображение карты C++

Каким образом можно отобразить OpenStreetMap карту средствами C++/Qt (БЕЗ QML)?

204