[英]Corrupted struct char arrays - sqlite C++
我对这个有点困惑。 到目前为止,使用 SQLite 一切都很好,但现在我试图将查询结果存储在一个简单的结构中。 当我在回调中执行此操作时,我的所有数据在我的 SQLItems 向量中看起来都很棒,但是一旦回调退出,我的 SQLItems 向量就会突然损坏保存我的数据行。 任何想法可能导致这种情况?
// Simple struct to hold column name and row data
struct SQLrow {
char * Column;
char * Data;
};
// static Vector to hold SQL rows
static std::vector<SQLrow> SQLItems;
...
// static callback that handles placing query results into structs and into SQLItems vector
// SQLItems column/row data gets corrupted after this function exits
static int countTablesCallback(void *data, int count, char **rows, char **azColName) {
int i;
for (i = 0; i < count; i++) {
SQLrow newItem = { azColName[i] ,rows[i] };
SQLItems.push_back(newItem);
}
*static_cast<std::vector<SQLrow>*>(data) = SQLItems; // Tried this too but throws an exception
return 0;
}
我还认为也许只能从回调静态转换以保存向量,但这也会引发异常。 难倒在这里。 感谢您的任何建议!
你的向量很好, static_cast
在那里没有意义,除非data
实际上被用作输出参数。 您的问题很可能是SQLrow
保存字符指针,而 SQLite 在回调返回后删除指向的字符串。 将您的课程更改为
struct SQLrow {
std::string Column;
std::string Data;
};
应该可以解决问题。
仅查看代码,一旦回调返回, rows
指向的数据似乎将失效/销毁/更改。 所以你不能保留这些指针供以后使用,并且必须制作数据的副本。
一种简单的方法是将Column
和Data
从char *
更改为std::string
。 如果做不到这一点,您将不得不进行某种手动内存管理(用new
分配空间,然后稍后删除),这很容易出错,而且现在不太可取。
在我看来,您想要/需要在 C++ 中使用原始字符串的情况很少,而您的情况不是其中之一。 顺便说一句,我希望这会以某种方式帮助您或其他人:
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
struct SQLrow {
char* Column;
char* Data;
};
void your_callback(int count, char **rows, char **azColName) {
std::vector<SQLrow> rows_list;
for (int i = 0; i < count; i++) {
/* Uncomment this if you want
your copy of the strings. If you
use this, don't forget to free the
memory yourself with delete[] s1 and
s2.
size_t s1_len = strlen(rows[i]);
size_t s2_len = strlen(azColName[i]);
char* s1 = new char [sizeof(char) * (s1_len + 1)];
char* s2 = new char [sizeof(char) * (s2_len + 1)];
memcpy(s1, rows[i], s1_len);
s1[s1_len] = '\0';
memcpy(s2, azColName[i], s2_len);
s2[s2_len] = '\0';
SQLrow r = { s1, s2 }; */
SQLrow r = { rows[i], azColName[i] };
rows_list.push_back(r);
}
// test the result
for (int i = 0; i < count; i++) {
SQLrow r = rows_list.at(i);
std::cout << "rows:" << r.Column << " azColName:" << r.Data << std::endl;
}
}
// this 2 lines are just for simulating the data
// you will get this 'warning: ISO C++ forbids converting a string constant to char*''
char* rows[] = {"row1", "row2" , "row3" };
char* colName[] = {"name1", "name2", "name3" };
int main()
{
your_callback(3, rows, colName);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.