【问题标题】:Creating an 2D Array of char* an fill it with data from sqlite in callback function在回调函数中创建一个 char* 的 2D 数组并用来自 sqlite 的数据填充它
【发布时间】:2016-10-18 20:46:20
【问题描述】:

在我的函数中,我使用 callback 函数调用 rc = sqlite3_exec(db, sqlStatement, callback, &a, &zErrMsg); 函数。 在这个 callback 函数中,我想用数据库中的数据填充一个 char* 的二维数组。

struct mytable 
{
    char ***data;
    size_t dim;
};

static int callback(void *data, int argc, char **argv, char **azColName)
{
    struct mytable *old = (mytable *)data;
    char ***temp;

    old->dim++;
    temp = (char ***)realloc(old->data, old->dim * sizeof(*old->data));
    if (temp) 
    {
        old->data = temp;
        old->data[old->dim - 1] = NULL;
    }
    else 
    {
        logging_logError("Kein virtueller RAM mehr vorhanden ... !", __FILE__);
        return EXIT_FAILURE;
    }

    for (int i = 0; i < old->dim; i++) 
    {
        char **temp2 = (char **)realloc(old->data[i], sizeof(argv) * sizeof(*old->data[i]));

        if (temp2) 
        {
            old->data[i] = temp2;
            old->data[i][argc - 1] = NULL;
        }
        else 
        {
            logging_logError("Kein virtueller RAM mehr vorhanden ... !", __FILE__);
            return EXIT_FAILURE;
        }
    }

    /*Here I try to store the data from each column 
     in the corresponding position in the 2D array of char* */
    for (int i = 0; i < argc; i++)
    {
        char *s = argv[i];
        temp[old->dim - 1][i] = s;
    }
    return 0;
}

当我打印出我返回的数据时,我得到了一些神秘的迹象。 我想要的是这样的(在数组结构中):

["1"]["Paul"]["street 1"]["some address"]
["2"]["Anna"]["street asdf"]["some address"]
["3"]["Martin"]["street bfg"]["some address"]

编辑: 这是我之前的question

【问题讨论】:

  • 对于初学者来说,你不应该投 realloc (可能不是你的问题的原因,但你仍然不应该这样做)
  • @UnholySheep。当我删除演员表时,编译器指出他不能从 void* 转换为 char***。顺便说一句,我正在使用 VS 2015。
  • 强制转换是可选的,不建议在 C 中使用,但在 C++ 中是必需的。从历史上看,VS 作为 C 编译器一直很古怪且不符合标准,尽管我听说 VS 2015 在这方面比旧版本更好。如果必须,请使用强制转换,但如果您可以设置一些项目选项来告诉 VS 充当符合标准的 C 编译器,那么这将是更可取的。请注意,C 和 C++ 之间存在比这更危险的差异。

标签: c arrays sqlite malloc


【解决方案1】:

我没有发现它具体记录,但似乎只有在回调返回之前,传递到回调中的 argv 字符串才有效。我看不出 SQLite 会如何工作——回调不负责管理这些字符串的内存,所以 SQLite 必须在内部这样做。

因此,不要在数组中记录原始字符串指针,而是复制字符串,并存储指向副本的指针。 MSVC++ 提供了strdup(),所以你可以通过替换...

        char *s = argv[i];

...与...

        char *s = strdup(argv[i]);

。请注意,通过这样做,您将承担在使用完这些字符串后释放这些字符串的责任。

【讨论】:

  • 非常感谢约翰。这就是问题所在。现在我得到了返回的完整数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多