C 中的 sqlite3 扩展函数和参数生命周期动态

问题描述 投票:0回答:1

下面是

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}?                                                                     
}
c sqlite
1个回答
1
投票

您不能指望

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()
进行了自己的分配,则可以使用任何释放该内存的函数来代替)。

© www.soinside.com 2019 - 2024. All rights reserved.