首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sqlite3_bind_blob什么时候释放内存是安全的?

sqlite3_bind_blob什么时候释放内存是安全的?
EN

Stack Overflow用户
提问于 2018-01-07 15:16:07
回答 3查看 2.4K关注 0票数 3

我有这样的工作守则:

代码语言:javascript
运行
复制
const char sql[] = "INSERT INTO test (pk, geom) VALUES (?, ?)";
sqlite3_stmt *stmt;
sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);

for (...) {
        sqlite3_reset (stmt);
        sqlite3_clear_bindings (stmt);
        int blob_size = ..;
        unsigned char *blob = malloc(blob_size);
        sqlite3_bind_int64 (stmt, 1, pk);
        sqlite3_bind_blob (stmt, 2, blob, blob_size, free);
        sqlite3_step (stmt);
}

我想知道,在周期的每一步,都不可能分配和自由分配吗?如果我将SQLITE_STATIC而不是free传递给sqlite3_bind_blob,并在循环结束后调用free,那么该代码是否仍然有效?

代码语言:javascript
运行
复制
const char sql[] = "INSERT INTO test (pk, geom) VALUES (?, ?)";
sqlite3_stmt *stmt;
sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
int capacity = 1024;
unsigned char *blob = malloc(capacity);

for (...) {
        sqlite3_reset (stmt);
        sqlite3_clear_bindings (stmt);
        int blob_size = ..;
        if (capacity < blob_size) {
           blob = realloc(blob, blob_size);
           capacity = blob_size;
        }
        sqlite3_bind_int64 (stmt, 1, pk);
        sqlite3_bind_blob (stmt, 2, blob, blob_size, SQLITE_STATIC);
        sqlite3_step (stmt);
}
free(blob);
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-07 17:01:43

使用SQLITE_STATIC需要该值保持有效,只要语句可以访问它。

您的代码应该是有效的;但是要确定的是,将对sqlite3_clear_bindings()的调用(和重置)移到循环的末尾。

票数 1
EN

Stack Overflow用户

发布于 2020-10-21 13:25:03

问题:如果我在循环结束后通过SQLITE_STATIC free 而不是free sqlite3_bind_blob 并调用 free ,那么该代码是否仍然有效?< code >E 221

答:No.

sqlite3_bind_blob()

如果第五个参数的值为SQLITE_TRANSIENT,那么SQLite将在sqlite3_bind_*()例程返回之前立即创建自己的数据私有副本。

这意味着当第五个参数没有这个值时(特别是当第五个参数具有SQLITE_STATIC值时),SQLite可能在例程返回之后仍然需要数据。在这种情况下,不保证SQLite可能需要多长时间的数据(除非,SQLite在调用sqlite3_close()之后不需要任何东西)。

票数 1
EN

Stack Overflow用户

发布于 2018-01-07 17:10:55

来自SQLite 文档

BLOB和string绑定接口的第五个参数是一个析构函数,用于在SQLite完成BLOB或string之后释放BLOB或string。即使绑定API调用失败,也会调用析构函数来释放BLOB或string。如果第五个参数是特殊值SQLITE_STATIC,那么SQLite假定信息位于静态的非托管空间,不需要释放。如果第五个参数的值为SQLITE_TRANSIENT,那么SQLite将在sqlite3_bind_*()例程返回之前立即创建自己的数据私有副本。

如果要重新分配内存,则应该使用SQLITE_TRANSIENT。那样的话,SQLite就不会做任何关于能够依赖内存的假设,它会自己复制。

请注意,文档没有确切地说明何时调用指定的析构函数(如果有的话) --只是在SQLite完成BLOB时调用它。如果您不想使用SQLITE_TRANSIENT,那么就不应该使用SQLITE_STATIC,因为当内存实际上不再可用时,SQLite可能会或者不认为它是可用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48138521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档