SQLite 3 语句准备段错误

SQLite 3 statement preparation segfault

我在我的 C 应用程序中使用 SQLite 3。直到现在,当我开始编写单元测试时,它一直很有效。有问题的功能非常小。它打开一个内存数据库,准备一条语句,然后用它做一些事情。问题是应用程序在 sqlite3_prepare_v2 函数调用时因分段错误而崩溃。我尝试调试它并检查所有参数是否有效,它们似乎是有效的。

下面,我粘贴了一个以相同方式导致段错误的最小示例。回溯将 sqlite3LockAndPrepare 列为崩溃的函数(由 sqlite3_prepare_v2 调用)。

正如我上面提到的,我在我的应用程序的其余部分中使用 SQLite 没有任何问题。我只是无法弄清楚用法上的区别是什么,因为它被分成几个不同的例程,这些例程也做其他事情。我可以发现的一件事是使用内存数据库而不是磁盘上的数据库,但我在磁盘上尝试过,但没有任何区别。

#include <stdlib.h>
#include <stdio.h>
#include <sqlite3.h>

int main(void)
{
    sqlite3 *db;
    sqlite3_stmt **stmt;
    const char *str = "CREATE TABLE Test (t1 varchar(8) NOT NULL);";

    if (SQLITE_OK != sqlite3_open(":memory:", &db)) {
        printf("Can't open...\n");
        return 1;
    }

    sqlite3_prepare_v2(db, str, -1, stmt, NULL);

    return 0;
}

sqlite3_prepare_v2() 的第四个参数应该是指向 sqlite3_stmt * 的有效指针。您传递的是一个未定义的值(因为您的变量 stmt 从未被初始化)。 (还要注意,即使那没有使程序崩溃,您也无法通过这种方式接收到准备好的语句的指针。)

你应该这样做,而不是:

int main(void)
{
    sqlite3 *db;
    sqlite3_stmt *stmt;
    const char *str = "CREATE TABLE Test (t1 varchar(8) NOT NULL);";

    /* ... create database ... */    

    sqlite3_prepare_v2(db, str, -1, &stmt, NULL);

    return 0;
}