2012-02-27 50 views
0

我从mysql数据库获取值,我想用返回的每一行来组织它。这里是我的结构(例如只):C动态数组中的分段错误

typedef struct 
{ 
    char* name; 
    char* etc; 
    int state; 

} person; 

和MySQL:

MYSQL * con; 
mysql_connect(&con); //connect to mysql database and set handle to con variable. 
MYSQL_ROW row; 
MYSQL_RES * result; 
int num_fields, i; 
mysql_query(con, "select name,etc,state from db.tbl"); 
result = mysql_store_result (con); 
num_fields = mysql_num_fields (result); 
person tempdata; 
person personlist[num_fields * sizeof(person)]; //the size if the problem, I believe... 
while((row = mysql_fetch_row (result))) { 
    tempdata.name = row[0]; 
    tempdata.etc = row[1]; 
    tenpdata.state = atoi(row[2]); 
    personlist[i++] = tempdata; // the error line 
} 

mysql_free_result (result); 
mysql_close (con); 

但它返回Segmentation fault如何解决这一问题?提前致谢。

+0

使用调试器(例如gdb)并尝试找到发生分段错误的行。 – Zeta 2012-02-27 14:42:07

+0

分段故障发生在哪里?我们无法复制您的整个测试设置,因此您提供的任何和所有信息都只能帮助您。 – tbert 2012-02-27 14:43:11

回答

2

当您声明一个结构数组时,可以将其大小指定为元素数。您的案件中的人数。声明它没有sizeof(person)person personlist[num_fields];

您还可以在不初始化的情况下使用变量i。将其声明更改为int num_fields, i = 0;

并注意tempdata.name = row[0];使得name指向与指向row[0]指向相同的数据。你可能想分配内存name和复制row[0]到它(检查展开答案)。

1
int num_fields, i;//Then you have not set a initial value to the variable i. 
5

您不复制字符串。你只是存储指针,这些指针在MySQL结果被释放后可能会立即失效。

您需要使用strdup()或等价物创建字符串的本地副本,现在您只是将指针存储到MySQL的数据中。

如果你没有的话,这里有一个快速和肮脏的更换:

char * my_strdup(const char *string) 
{ 
    if(string != NULL) 
    { 
    const size_t slen = strlen(string); 
    char *out = malloc(slen + 1); 
    if(out != NULL) 
    { 
     strcpy(out, string); 
     return out; 
    } 
    } 
    return NULL; 
} 

注意,它不是叫strdup(),因为这是一个保留的名称。

+2

+1注意。我没有注意到这个;) – LihO 2012-02-27 14:50:04

1

mysql_num_fields返回结果集中的列数。在32位系统上,sizeof(person)将为12个左右。 i未初始化。

您需要i以从零开始,并且您希望有足够的存储空间用于行,而不是12倍的列数。

0

除了字符串拷贝的问题前面提到的:

person personlist[mysql_num_rows(result)]; 

你需要足够的存储空间的行数,而不是字段的数量。