Ошибка сегментации в динамическом массиве C - PullRequest
0 голосов
/ 27 февраля 2012

Я получаю значения из базы данных mysql, я хочу организовать их по каждой возвращаемой строке.вот моя структура (только пример):

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 как это исправить?заранее спасибо.

Ответы [ 5 ]

5 голосов
/ 27 февраля 2012

Вы не копируете строки. Вы просто храните указатели, которые, вероятно, становятся недействительными, как только результаты 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 голосов
/ 27 февраля 2012

Когда вы объявляете массив структур, вы указываете его размер в виде числа элементов.Количество человек в вашем случае.Объявите это без sizeof(person): person personlist[num_fields];.

Вы также используете переменную i без инициализации.Измените его объявление на int num_fields, i = 0;.

И обратите внимание, что tempdata.name = row[0]; заставляет name указывать на те же данные, на которые указывает row[0].Вы, вероятно, хотите выделить память для name и скопировать в нее row[0] (отметьте, чтобы развернуть ответ).

1 голос
/ 27 февраля 2012

mysql_num_fields возвращает количество столбцов в вашем наборе результатов.sizeof(person) будет 12 или около того в 32-битной системе.i не инициализируется.

Вам нужно i, чтобы начать с нуля, и вам нужно достаточно места для хранения строк, а не в 12 раз больше количества столбцов.

1 голос
/ 27 февраля 2012
int num_fields, i;//Then you have not set a initial value to the variable i.
0 голосов
/ 27 февраля 2012

В дополнение к проблеме копирования строк, упомянутой ранее:

person personlist[mysql_num_rows(result)];

Вам нужно достаточно места для хранения количества строк, а не количества полей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...