【发布时间】:2018-01-29 21:33:05
【问题描述】:
我正在尝试在 C 中创建一个字符串矩阵来存储 sql 回调的结果。由于某种原因,即使数据的内存地址相同,它总是在“数据”的第 12 次重新分配时崩溃。 谢谢。
int row_index;
static int db_select_cb(void *p_data ,int argc, char **argv, char **azColName){
char ***data = (char ***)p_data;
data = (char ***)realloc(data,sizeof(char **)*(row_index+1));
data[row_index] = (char **)malloc(sizeof(char *)*(argc));
for(int col_index = 0;col_index < argc;col_index++){
data[row_index][col_index] = (char *)malloc(sizeof(char)*(strlen(argv[col_index])+1));
strcpy(data[row_index][col_index],argv[col_index]);
}
row_index++;
return 0;
}
char ***db_select(sqlite3 *conn,unsigned char *zSQL){
row_index = 0;
char ***data = (char ***)malloc(sizeof(char ***)*(row_index+1));
char *err = 0;
int cerr = sqlite3_exec(conn,zSQL,db_select_cb,(void*)data,&err);
if(cerr){
printf(":: SQL ERROR IN \"db_select\" || %s ||\n", err);
sqlite3_free(err);
return 0;
}
return data;
}
感谢你们的帮助。问题是我需要将对矩阵的引用传递给回调,因为 realloc 正在修改数据。这就是最终的工作。
int row_index;
static int db_select_cb(void *p_data ,int argc, char **argv, char **azColName){
char ****data = (char ****)p_data;
*data = realloc(*data,sizeof(char **)*(row_index+1));
(*data)[row_index] = malloc(sizeof(char *)*(argc));
for(int col_index = 0;col_index < argc;col_index++){
(*data)[row_index][col_index] = malloc(sizeof(char)*(strlen(argv[col_index])+1));
strcpy((*data)[row_index][col_index],argv[col_index]);
}
row_index++;
return 0;
}
char ***db_select(sqlite3 *conn,unsigned char *zSQL){
row_index = 0;
char ***data = malloc(sizeof(char **)*(row_index+1));
char *err = 0;
int cerr = sqlite3_exec(conn,zSQL,db_select_cb,(void*)&data,&err);
if(cerr){
printf(":: SQL ERROR IN \"db_select\" || %s ||\n", err);
sqlite3_free(err);
return 0;
}
return data;
}
这是一个使用结构的更新解决方案,正如 Groo 指出的那样,这是跟踪行和列大小的唯一方法。
typedef struct{
char ***data;
int row_size;
int *col_size;
}Table;
static int db_select_cb(void *p_table ,int argc, char **argv, char **azColName){
Table **table = (Table **)p_table;
(*table)->data = realloc((*table)->data,sizeof(char **)*((*table)->row_size+1));
(*table)->data[(*table)->row_size] = malloc(sizeof(char *)*(argc));
(*table)->col_size = realloc((*table)->col_size,sizeof(int)*((*table)->row_size+1));
int col_index;
for(col_index = 0;col_index < argc;col_index++){
(*table)->data[(*table)->row_size][col_index] = malloc(sizeof(char)*(strlen(argv[col_index])+1));
strcpy((*table)->data[(*table)->row_size][col_index],argv[col_index]);
}
(*table)->col_size[(*table)->row_size] = col_index;
(*table)->row_size++;
return 0;
}
Table *db_select(sqlite3 *conn,unsigned char *zSQL){
Table *table = malloc(sizeof(Table));
table->row_size = 0;
table->data = NULL;
table->col_size = NULL;
char *err = 0;
int cerr = sqlite3_exec(conn,zSQL,db_select_cb,(void*)&table,&err);
if(cerr){
printf(":: SQL ERROR IN \"db_select\" || %s ||\n", err);
sqlite3_free(err);
return 0;
}
return table;
}
【问题讨论】:
-
我不记得以前在一个问题中看到过这么多星星:(
-
一个三星级程序员应该知道如何使用调试器。
-
XD 我知道如何使用 valgrind,但是 Windows 上的所有调试器都在付费墙后面,或者并没有真正告诉我太多。
-
@TheAschr 您的代码是一个巨大的多级 UB。我的建议 - 重新考虑再写一遍
-
I always thought those were discouraged in C你从哪里得到这些信息的?
标签: c arrays matrix dynamic allocation