2012-02-27 51 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)]; 

你需要足夠的存儲空間的行數,而不是字段的數量。