2012-02-27 15 views
0

私はmysqlデータベースから値を取得していますが、返された各行で整理したいと思います。Cの動的配列のセグメンテーションフォールト

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を返します。

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

} person; 

とMySQL:ここに私の構造体は、(例のみ)ですか?前もって感謝します。

+0

デバッガ(gdbなど)を使用して、セグメンテーション違反が発生する行を探してみます。 – Zeta

+0

セグメンテーションフォルトはどこで発生しますか?テストセットアップ全体を複製することはできませんので、提供できるすべての情報はあなたを助けるだけです。 – tbert

答えて

2

構造体の配列を宣言するときは、要素の数としてそのサイズを指定します。あなたのケースの人数。 sizeof(person)person personlist[num_fields];なしで宣言してください。

また、変数iを初期化せずに使用します。宣言をint num_fields, i = 0;に変更します。

nameと同じデータを指しています。row[0]を指します。あなたはおそらくnameのためのメモリを割り当て、それにrow[0]をコピーしたいと思うでしょう(check unwinds answer)。

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

1

mysql_num_fields結果セットの列数を返します。 sizeof(person)は、32ビットシステムでは12程度になります。 iは初期化されません。

ゼロから開始するには、iが必要で、列の数の12倍ではなく、行に十分な記憶域が必要です。

0

前述した文字列のコピーの問題に加えて:

person personlist[mysql_num_rows(result)]; 

あなたは行数ではなく、フィールドの数のための十分なストレージを必要としています。