Вот что документация говорит о причинах вашей ошибки:
- Вызов любой подпрограммы API с указателем sqlite3 *, который не был
полученный из sqlite3_open () или sqlite3_open16 () или который имеет
уже был закрыт sqlite3_close ().
- Попытка использовать одно и то же соединение с базой данных в одно и то же время в
время из двух или более потоков.
- Вызов sqlite3_step () с указателем оператора sqlite3_stmt *, который
не был получен из sqlite3_prepare () или sqlite3_prepare16 () или
это уже было уничтожено sqlite3_finalize ().
- Попытка связать значения с оператором (используя sqlite3_bind _... ()) во время выполнения этого оператора.
Вы упомянули попытку критического раздела, так что я думаю, мы можем исключить # 2. Ваша ошибка является результатом вызова sqlite3_prepare_v2 (...), а не sqlite3_step () или или sqlite3_bind (), поэтому я предполагаю, что остается только номер 1? Можете ли вы дважды проверить, что ваш указатель БД хорош? Отследить его до sqlite3_open (), который его возвратил, и убедиться, что ничто не закрыло его перед тем, как вызывается ваша подготовка?
Это работает для меня:
#include <stdio.h>
#include <sqlite3.h>
int main(int argc, char **argv){
sqlite3 *db;
int rc;
char *db_name= ":memory:";
rc = sqlite3_open(db_name, &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "failed to open in memory database: %s\n",
sqlite3_errmsg(db));
sqlite3_close(db);
return(1);
}
const char *create_sql = "CREATE TABLE foo(bar TEXT)";
sqlite3_stmt *statement;
rc = sqlite3_prepare_v2(db, create_sql, -1, &statement, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "failed to prepare statement: %s\n",
sqlite3_errmsg(db));
sqlite3_close(db);
return(1);
}
rc = sqlite3_step(statement);
if (rc == SQLITE_ERROR) {
fprintf(stderr,
"failed to execute statement: %s\n",
sqlite3_errmsg(db));
}
sqlite3_close(db);
}