代码之家  ›  专栏  ›  技术社区  ›  gibarsin

我是否必须对SQLITE中argv回调中的每个参数进行深度复制?

  •  1
  • gibarsin  · 技术社区  · 9 年前

    如果我想在调用回调时存储查询返回的信息,我应该对 argv语言 或者我可以安全地假设sqlite3在从回调返回后不会释放它吗?我正在使用C作为编程语言。

    static int callback_consult(void *dummy, int argc, char **argv, char **col_name) {
      res_consult_t * answer = &(global_answer -> consult_res);
      movie_t *curr_tuple = calloc(sizeof(char), sizeof(movie_t));
    
      /* Should I memcpy ??? */
      curr_tuple -> name = argv[0];
      curr_tuple -> genre = argv[1];
      curr_tuple -> description = argv[2];
      curr_tuple -> seats_available = argv[3]; /* Convert to int */
    
      (answer -> movies)[tuple] = curr_tuple;
    
      return SQLITE_OK;
    }
    
    1 回复  |  直到 9 年前
        1
  •  1
  •   John Bollinger    9 年前

    我猜你在问回调函数传递给什么 sqlite3_exec() 可以安全地进行。

    首先 sqlite3_exec() 这样说:

    sqlite3_exec()回调的第三个参数是指向字符串的指针数组,就像从sqlite3_column_text()中获得的一样,每列一个。如果结果行的元素为NULL,则sqlite3_exec()回调的对应字符串指针为NULL指针。

    一般来说,你 因此需要为结果列做好准备 NULL 。是否安全或适当地分配 无效的 程序中的任何特定变量、结构或联合成员或数组元素都是程序的特征。通过肯定不安全 无效的 作为 memcpy() strcpy() 不过,因此您可能需要对此进行解释。

    的文档 sqlite3_column_text() 不过,还是要触及问题的核心。尤其适用于:

    返回的指针有效,直到如上所述发生类型转换,或者调用sqlite3_step()或sqlite3_reset()或sqlserver3_finalize()。用于保存字符串和BLOB的内存空间将自动释放。

    自从

    sqlite3_exec()接口是sqlite3_prepare_v2()、sqlite3_step()和sqlite3_finalize()[…]的便利包装。

    总的结论是,字符串通过参数传入回调函数 argv 仅在回调返回之前可用。如果要保存这些结果以供以后处理,则需要制作副本,或以其他方式从中提取所需的数据。