下面是
C
中针对 sqlite3
3.45.1 的工作功能扩展。
问题是关于 sqlite3_value_blob
上输入的指针动力学和输入材料的生命周期,并通过 sqlite_return_text
返回,并位于函数底部的注释中:
static void get_some_string_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
assert( argc==1 );
// We store struct mytype* in a BLOB so fetch it:
const mytype* mytype_inst = (const mytype*)sqlite3_value_blob(argv[0]);
// OK, so mytype_inst is a pointer into memory coming in on
// argv[0]. I now call this function which is defined to return
// a pointer to a string NOT NECESSARILY NULL TERMINATED inside
// (struct mytype*), and that pointer is NOT TO BE freed; note the len is
// passed back via &len:
uint32_t len;
const char* s = mytype_get_some_string(mytype_inst, &len);
// I now wish to return that string.
// The absolute safest way is this because a copy of s
// of the appropriate len will be made:
sqlite3_result_text(context, s, len, SQLITE_TRANSIENT);
// But since s is a pointer into mytype_inst which came in on
// argv[0], is there a more efficient way to do this, e.g.?
sqlite3_result_text(context, s, len, SQLITE_STATIC);
// In other words, what are the malloc/free pointer dynamics
// between
// sqlite3_value **argv
// and
// sqlite3_result_{text,blob,text16}
// ?
// What parts of sqlite3_value **argv have a lifetime that exceeds -- or NOT --
// processing of the material returned in sqlite3_result_{text,blob,text16}?
}
您不能指望
sqlite3_value_blob()
返回的指针在函数返回后有效。事实上,您不能总是指望它在函数的生命周期内有效。来自文档:
请特别注意,从
、sqlite3_value_blob()
或sqlite3_value_text()
返回的指针可能会因后续调用sqlite3_value_text16()
、sqlite3_value_bytes()
、sqlite3_value_bytes16()
或sqlite3_value_text()
而失效。sqlite3_value_text16()
将
SQLITE_STATIC
作为析构函数参数传递给结果函数是一个承诺,即指针将永远保持有效(或者至少在当前 SQL 语句正在执行时,或者更好的是在数据库连接的生命周期内)。这个承诺在这里不成立。
因此,像您当前正在做的那样使用
SQLITE_TRANSIENT
是合适的事情(如果您的 mytype_get_some_string()
进行了自己的分配,则可以使用任何释放该内存的函数来代替)。