gpt4 book ai didi

c - SQLite 在我第二次使用 sqlite3_prepare_v2 时崩溃

转载 作者:太空宇宙 更新时间:2023-11-03 23:27:18 26 4
gpt4 key购买 nike

我在使用 SQLite 时遇到与内存管理相关的崩溃。除非我在 Xcode 中启用 Guard Malloc(一种测试模式),否则它每 30 次左右尝试只会崩溃一次,在这种情况下,它会在我第二次准备语句时崩溃,100% 的时间。我认为这与我打开或使用数据库的方式有关,但我找不到任何错误,但我是 SQLite 的新手。有什么我忘记了吗?

打开包装函数:

int databaseConnect(sqlite3 **db){
int rc = sqlite3_open_v2(dbURL, db, SQLITE_OPEN_READWRITE, NULL);
if(rc!=SQLITE_OK){
fprintf(stderr, "Can't open database! Error: %s\n", sqlite3_errmsg(*db));
sqlite3_close_v2(*db);
return(SQL_ERROR);
}
return NO_ERROR;
}

发送命令的封装函数:

int databaseCommand(char* command, sqlite3* db){
char* error = NULL;
int ret = sqlite3_exec(db, command, NULL, 0, &error);
if (ret!=SQLITE_OK){
printf("SQL command aborted. Error: %s\n", error);
return SQL_ERROR; //EDIT: this will cause the database to close later
}
if (error) sqlite3_free(error);
return NO_ERROR;
}

我如何使用我的打开功能:

//ONCE IN MAIN THREAD, BEFORE ANY OTHER THREADS:
sqlite3* db = NULL;
databaseConnect(&db);
//call databaseCommmand a few times while creating tables...
sqlite3_close_v2(db);

//ONCE PER THREAD IN OTHER THREADS:
sqlite3* db = NULL; databaseConnect(&db);

我如何在我的非主线程中使用 sqlite3_prepare_v2(以及崩溃的地方):

struct LinkedList* databaseSelect(char* command, sqlite3* db){
sqlite3_stmt* stmt = NULL;
int retval = retval = sqlite3_prepare_v2(db,command,(strlen(command))*sizeof(char),&stmt,NULL); //crashes here the second time I run it
if(retval!=SQLITE_OK){
printf("Selecting data from database failed! Error: %s\n", sqlite3_errmsg(db));
sqlite3_free(stmt);
return NULL; //EDIT: this will cause the database to close later
}
// Then the function does stuff involving sqlite3_column_text and sqlite3_column_int…
sqlite3_free(stmt);
// return the linked list result
}

我得到的错误以及导致错误的 SQLite3 库部分:

EXC_BAD_ACCESS (code=1) in this part of sqlite3.c:
/*
** Create a new virtual database engine.
*/
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
Vdbe *p;
p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
p->db = db;
if( db->pVdbe ){
db->pVdbe->pPrev = p; //error is right here; db->pVdbe is pointing to invalid address
}
p->pNext = db->pVdbe;
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
return p;
}

每当我使用 sqlite3_column_text 时,我都会立即复制结果。我不修改结果。在 databaseCommand 和 databaseSelect 中,char* 命令以 null 结尾且有效(我检查过)。每个线程都使用自己的数据库句柄,每个都连接到同一个数据库。但是,在此测试用例中,在任何给定时间只有一个线程连接到数据库。

如果这里真的没有问题,我必须假设我在我的程序的其他地方践踏了内存,而且我在程序的其余部分找不到任何看起来有点危险的东西。此外,值得怀疑的是 SQLite 是每次崩溃的原因。

最佳答案

sqlite3_prepare_v2 documentation说:

The calling procedure is responsible for deleting the compiled SQL statement using sqlite3_finalize() after it has finished with it.

sqlite3_free()只能用于使用 sqlite3_alloc() 分配的原始内存,或者当像 sqlite3_exec() 这样的函数时被记录为需要它。

关于c - SQLite 在我第二次使用 sqlite3_prepare_v2 时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23508073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com