Хранение строк в динамической структуре - PullRequest
0 голосов
/ 27 июля 2011

Я пишу функцию, которая хранит строки из stdin и динамически распределяет память для него в структуре.Когда я компилирую свой код, я получаю 3 ошибки и не понимаю, почему я получаю эти ошибки.

Ошибки следующие:

error: incompatible types in assignment
error: incompatible type for argument 1 of `strcpy'
error: incompatible type for argument 1 of `free'

Вот функция:

#define NAMESIZE 20
#define BLOCK 2
typedef struct
{
char last[NAMESIZE];
char first[NAMESIZE];
}name;

typedef struct
{
int id;
name name;
float score;
}record;

typedef struct
{
record *data;
size_t nalloc;
size_t nused;
}record_list;


int list_insert(record_list *list, const record *rec)
{
char * temp;
char lines[512];
size_t i;
list->nalloc = 0;
list->nused = 0;

while(fgets(lines, 512, stdin))
{
    if(list->nalloc == list->nused)
    {
        temp = realloc(list->data, (list->nalloc + BLOCK) * sizeof(char *));

        if(temp == 0)
        {
            fprintf(stderr, "Unable to resize memory\n");
            break;
        }

        list->data = (record *)temp;
        list->nalloc += BLOCK;
    }
    list->data[list->nused] = malloc(strlen(lines) + 1); /*problem line*/
    strcpy(list->data[list->nused++], lines);/*problem line*/

}
for(i = 0; i < list->nused; i++)
{
    free(list->data[i]); /*problem line*/
}
free(list->data);


return 0;
}

Будет нужна любая помощь.

Ответы [ 3 ]

1 голос
/ 27 июля 2011

Ваш код, похоже, использует list->data[i] в качестве указателя, но поскольку list->data является record*, то list->data[i] является record, а не record*.

С вашими текущими структурами данных требуется только одна пара malloc / free; все, кроме list->data, имеет известную и постоянную длину.

Теперь ваш realloc действительно неверен, вам нужно выделить кратное sizeof (*list->data) (т.е. sizeof (record)). Ваш код также потерпит неудачу, если первый вызов realloc вернет ноль (вы выходите из цикла и пытаетесь освободить list->data, который может быть нулевым).

1 голос
/ 27 июля 2011
list->data[list->nused] = malloc(strlen(lines) + 1);

list->data имеет тип record *, но вы обращаетесь к нему (с [list-nused]), так что тип list->data[list->nused] равен record, и вы назначаете указатель на него.Чтобы это работало, элемент структуры data в record_list должен быть указателем на указатель.

Кроме того, вы хотите выделить память для строки (так как вы выделяете strlen(lines) + 1 байт),Но у вас нет никакой переменной для хранения строки: record имеет int, float и два символьных массива, которые имеют фиксированный размер.

Что вам, вероятно, нужно, это что-то вроде этого:

typedef struct {
    int id;
    char *name;
    float score;
} record;

...
temp = realloc(list->data, list->nalloc * sizeof(record));
...
list->data[list->nused].name = malloc(strlen(lines) + 1);
strcpy(list->data[list->nused++].name, lines);
...
free(list->data[i].name);

Таким образом, вы выделяете запись (int, char-указатель, float), а там, где указатель char, вы выделяете память для строки.

1 голос
/ 27 июля 2011

list->data - указатель на record, поэтому list->data[i] имеет тип record.Все ваши проблемные строки ожидают char * или, по крайней мере, какой-то указатель, что приводит к сообщениям об ошибках.

...