Jack
Jack

Reputation: 16724

Segmentation fault in C dynamic array

I'm getting values from mysql database, I want to organize it with each row returned. here's my struct(example only):

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

} person; 

and the 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);

but it returns Segmentation fault how to fix this? thanks in advance.

Upvotes: 0

Views: 628

Answers (5)

gcbenison
gcbenison

Reputation: 11963

In addition to the string-copying issue mentioned previously:

person personlist[mysql_num_rows(result)];

You need enough storage for the number of rows, not the number of fields.

Upvotes: 0

unwind
unwind

Reputation: 400129

You are not copying the strings. You are just storing pointers which are probably rendered invalid as soon as the MySQL results are freed.

You need to use strdup() or equivalent to create local copies of the strings, now you're just storing pointers into MySQL's data.

If you don't have it, here's a quick and dirty replacement:

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;
}

Note that it's not named strdup(), since that's a reserved name.

Upvotes: 5

LihO
LihO

Reputation: 42133

When you declare an array of structures, you specify its size as number of elements. Number of persons in your case. Declare it without sizeof(person): person personlist[num_fields];.

You also use variable i without being initialized. Change its declaration to int num_fields, i = 0;.

And note that tempdata.name = row[0]; makes name point to the same data as row[0] points to. You probably want to allocate memory for name and copy row[0] into it (check unwinds answer).

Upvotes: 2

Pete Kirkham
Pete Kirkham

Reputation: 49331

mysql_num_fields returns the number of columns in your result set. sizeof(person) will be 12 or so on a 32-bit system. i is not initialised.

You need i to start at zero, and you want enough storage for your rows, not 12 times the number of columns.

Upvotes: 1

xda1001
xda1001

Reputation: 2459

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

Upvotes: 1

Related Questions