Sqlite3 - 尝试在回调中填充结构

时间:2016-04-22 10:45:12

标签: c memory struct sqlite malloc

我有以下结构:

typedef struct {
    char *username;
    char *score;
} Highscore;

使用如下:

static int callback(void* data, int argc, char** argv, char** colName) {
  Highscore* highscore = (Highscore*)data;

  highscore->username = argv[0];
  highscore->score = argv[1];

  return 0;
}

数据库业务流程在这里使用了struct:

Highscore* getHighscore()
{
  sqlite3* db_handle;
  int rc;
  char* zErrMsg;
  Highscore* highscore = malloc(sizeof(Highscore));
  /* highscore->username = malloc(sizeof(100)); */
  /* highscore->score = malloc(sizeof(100)); */

  //Datenbankverbindung oeffnen
  rc = sqlite3_open(DATABASE_FILE, &db_handle);

  char* sSqlString = sqlite3_mprintf
    ("select U.Username, H.Punkte from Highscore H join User U on U.B_ID = H.B_ID order by Punkte desc limit 10");

  //SQL Statement ausfuehren
  rc = sqlite3_exec(db_handle, sSqlString, callback, highscore, &zErrMsg);

  //Datenverbindung schliessen und Speicher leeren
  sqlite3_free(sSqlString);
  rc = sqlite3_close(db_handle);

  return highscore;

}

现在出现的问题是,在回调范围内,Highscore结构已经分配了字段" username"和"得分"应该是这样的。我在那个位置调试过,一切都很好。

但是当我回到" getHighscore" Highscore struct的字段中包含任意值。我没有意识到发生了什么?我先将结构分配给" malloc"进行回调。我已经检查了回调后它是否是相同的地址 - 它是。那么为什么价值观会被破坏呢?

2 个答案:

答案 0 :(得分:1)

只保留Highscore结构中的指针,并覆盖实际值。试试这个:

static int callback(void* data, int argc, char** argv, char** colName)
{
  Highscore* highscore = (Highscore*)data;

  highscore->username = malloc( strlen( argv[0] ) + 1 );
  strcpy( highscore->username, argv[0] );
  highscore->score = malloc( strlen( argv[1] ) + 1 );
  strcpy( highscore->score, argv[1] );

  return 0;
}

不要忘记最后free scoreusernamefree - highscore之前)。

答案 1 :(得分:0)

sqlite3_exec() documentation说:

  

sqlite3_exec()回调的第三个参数是一个指向字符串的指针数组,就像从sqlite3_column_text()获得的那样,每列一个。

sqlite3_column_text() documentation说:

  

返回的指针有效,直到如上所述发生类型转换,或直到调用sqlite3_step()或sqlite3_reset()或sqlite3_finalize()为止

...在sqlite3_exec()返回之前发生。

您必须将字符串复制到您自己的缓冲区。最好使用具有动态字符串的语言。