sqlite3_bind_text中的SQLITE_STATIC与SQLITE_TRANSIENT对于C++字符串的区别

5

我有一个返回C++ std::string的方法,然后我将其转换为c_str(),在传递给sqlite3_bind_text之前。我的问题是,这应该使用SQLITE_STATIC还是SQLITE_TRANSIENT?

(SQLITE_STATIC和SQLITE_TRANSIENT都是sqlite3_bind_text函数中的参数,用于指定绑定的文本是否是静态的或临时的。)
sqlite3_bind_text(insertStatement, 0, suspect->GetIpString().c_str(), -1, SQLITE_STATIC);
// Do some stuff in same function then sqlite3_step

sqlite3_bind_text的文档表示:
sqlite3_bind_blob()、sqlite3_bind_text()和sqlite3_bind_text16()函数的第五个参数是一个析构器,用于在SQLite处理完后释放BLOB或字符串。即使调用sqlite3_bind_blob()、sqlite3_bind_text()或sqlite3_bind_text16()失败,析构器也会被调用以释放BLOB或字符串。如果第五个参数是特殊值SQLITE_STATIC,则SQLite假定信息位于静态的、不受管理的空间中,不需要释放。如果第五个参数的值为SQLITE_TRANSIENT,则SQLite会在sqlite3_bind_*()函数返回之前立即制作自己的私有副本。
GetIpString返回一个std::string,但如果没有显式复制它,那么这个字符串在调用结束后是否还存在?此外,在一般情况下使用.c_str()是否安全,而不使用SQLITE_TRANSIANT?我知道SQLITE_TRANSIENT是安全的选择,但如果不需要它,我想避免复制/性能问题,因为这个查询将会被频繁运行。
1个回答

10
在您的情况下,由GetIpString()返回的字符串对象很可能会在查询执行和完成之前被销毁,因此您应该使用SQLITE_TRANSIENT

通常情况下,除非您已经通过实际性能问题的测量确定了这一点,否则不需要担心临时副本。

并非完全如此,一个 blob 可能非常大,因此内存浪费/碎片化也可能成为问题。 - user1095108

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接