在3D阵列中存储2D阵列

时间:2016-08-17 10:44:37

标签: c arrays windows pointers memory

我目前正在尝试为数据库请求编写回调函数。 为每个结果/数据库条目/行调用该函数,我想将其2D数组(strings / char *数组)存储在数组中。 我目前的解决方案如下:

全球宣言:

char ***entries;

在设置功能中为第一个维度分配内存:

entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char **)*200);

我正在使用Windows API / Win32,基本上它是带有零内存的malloc,最后一个参数指的是大小。

初始化回调计数并为数据库执行注册回调函数:

cbCount = 0;
rc = sqlite3_exec(db, sql, insertListEntries, 0, &zErrMsg);

回调功能:

static int insertListEntries(void *NotUsed, int argc, char **argv, char **azColName) {
    entries[cbCount] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(argv)*argc); 
    memcpy(entries[cbCount], argv, sizeof(argv)*argc);
    ...
    cbCount++;
}

参数:argc是数据的argv /列的大小,argv是带有行数据的字符串数组。 我只是将argv的内存数据复制到3D数组中。

然而,现在的问题是,对于每个回调,所有以前的数据集都会被当前结果覆盖,如下所示:

回调1:条目[0] = dataset1

回调2:条目[0] = dataset2,entries [1] = dataset2

...

有什么想法吗?我仍然在尝试学习“指针/数组 - 二元论”和内存分配这个概念,但对我来说最好的方法就是实际做到这一点。另外,我事先研究了这个理论,但我可能错过了一些东西。

修改:添加了cbCount ++;

1 个答案:

答案 0 :(得分:1)

将评论转换为答案:

看起来sqlite重用缓冲区,实际上在argv向量中传递相同的指针用于不同的调用。

因此,当您第一次调用insertListEntriescbCount 0)时,参数argv可能包含指针值{ 0x1111100, 0x1111200, 0x1111300, ... },您将其复制到entries[0]阵列。

然后,当第二次调用insertListEntriescbCount 1)时,argv中的指针值至少部分或有时相同!这意味着,重新使用为结果数据分配的缓冲区,其内容已更改。因为您将指针复制到entries[0],现在将可能相同的指针复制到entries[1],它们将指向相同的字符串,每次调用都会被覆盖。

解决方案是复制实际的字符串,实际数据,而不是仅仅复制指向库内部缓冲区的指针。