Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C SQLite SQLite_静态局部变量问题_C_Sqlite_Dangling Pointer - Fatal编程技术网

C SQLite SQLite_静态局部变量问题

C SQLite SQLite_静态局部变量问题,c,sqlite,dangling-pointer,C,Sqlite,Dangling Pointer,我正在查看一些供应商代码,有这样一个查询: BOOL BindQuery(sqlite3_stmt* stmt, PARAMS* params) { char temp[150] = ""; char paramBuf[10] = ""; if (currStmt == NULL) return FALSE; sprintf(paramBuf, "%d", (int)params->someParam); strcpy(temp, "%");

我正在查看一些供应商代码,有这样一个查询:

BOOL BindQuery(sqlite3_stmt* stmt, PARAMS* params)
{
    char temp[150] = "";
    char paramBuf[10] = "";
    if (currStmt == NULL) return FALSE;

    sprintf(paramBuf, "%d", (int)params->someParam);
    strcpy(temp, "%");
    strcat(temp, tempVolt);
    strcat(temp, "%");
    sqlite3_bind_text(stmt, 4, temp, strlen(temp), SQLITE_STATIC);
    return TRUE;
}
之后,查询将被执行。问题是这个查询永远不会匹配,即使它应该匹配

我认为问题在于
sqlite3\u bind\u text
绑定了一个局部变量,而SQLite保留了指向原始局部变量的指针。因此,当它超出范围时,它可能已经被覆盖。修复方法似乎是使用
SQLITE\u TRANSIENT
。有人能证实我的想法吗?还是我偏离了基地


另一个奇怪的问题是,供应商从未能够复制它。运气好吗?

是的,这个代码是错误的。报告说:

如果第五个参数是特殊值SQLITE_STATIC,则SQLITE假定信息位于静态的非托管空间中

但这个局部变量不是静态的


如果堆栈的该部分在执行查询之前避免被覆盖,则此代码可能会工作。

如果有人在sqlite
C
ABI上创建一个现代的
C++
包装器,则 我们可以使用一个R值引用来选择性地使用SQL\u 对于传递的临时对象

像下面这样

class Statement
{
/*Other Logic*/
/* Other Bind() overloads using SQLITE_STATIC */
void Bind(const int index, std::string && text) const
{
  if(SQLITE_OK != sqlite3_bind_text(FetchABI(),index,text.c_str(),text.size(),SQLITE_TRANSIENT))
{
 // Error Handling
}
}
/* Bind overload for std::wstring */
};
当我们传递一个临时对象时,编译器足够聪明,可以选择正确的重载,因此我们避免了SQLite在每个地方都制作私有副本的成本(对于小型应用程序可能不需要这样做)

内干管()


注意:FetchABI()获取底层句柄,其实现取决于某人的突发奇想

“如果第五个参数的值为SQLITE_TRANSIENT,那么SQLITE会在sqlite3_bind_*()例程返回之前立即创建自己的数据私有副本。”听起来您是对的。
Statement obj;
obj.Prepare(cx,"Select ?1"); // cx is the connection not defined here for brevity
obj.Bind(1,std::string("This value is copied"));
// Or the second overload
obj.Bind(1,std::wstring(L"This too is copied"));