связанный список типа void * - PullRequest
0 голосов
/ 01 февраля 2011

Я пытаюсь прочитать текстовый файл и сохранить каждую строку в узле списка ссылок типа void *.Вот заголовочный файл списка.

#ifndef LINKEDL
#define LINKEDL

struct node_s {
    void *data;
    struct node_s *next;    
};

struct node_s *node_create(void*);
struct node_s *list_insert_after(struct node_s*, void*);
struct node_s *list_insert_beginning(struct node_s*, void*);
int list_remove(struct node_s*, struct node_s*);
int list_foreach(struct node_s*, int(*)(void*));
int printstring(void *s);


#endif

Все функции связанного списка были тщательно протестированы, поэтому я думаю, проблема в том, как я их использую.Чего я хочу добиться, так это иметь одну строку в каждом узле, и теперь у меня есть последняя строка в каждом узле.Я думаю, это как-то связано с указателями на символы, но уже потратил на это два часа без впечатляющего прорыва, так что, может быть, кто-то может помочь?Кроме того, список, который я использую, представляет собой измененный список, как видно здесь .

 if (file == NULL)
 {
    perror("Error opening file");
 }
 else 
 {
     char mystring[SIZE];
     char temp[SIZE];

     list = node_create((void*)mystring);
     current = list;
     while (fgets(mystring, SIZE, file) != NULL)
        {
            strcpy(temp, mystring); 
            printf("%d\t%s",counter++,temp);
            current=list_insert_after(current, (void*)temp);                    
            }
            fclose(file);

        }

ОБНОВЛЕНИЕ: Спасибо всем.

Ответы [ 3 ]

3 голосов
/ 01 февраля 2011

Вы создаете каждый узел, используя один массив, темп. Каждый раз, когда вы читаете строку, вы заменяете содержимое temp последней прочитанной строкой. Вот почему у вас есть последняя строка на каждом узле (вы ссылаетесь на одну и ту же ячейку памяти на каждом узле).

Что вы должны сделать, это динамически распределять память для каждой строки, используя malloc. Таким образом, вы должны передать указатель на вновь выделенную память в list_insert_after вместо передачи temp.

1 голос
/ 01 февраля 2011

Удалить строку:

strcpy(temp, mystring); 

И изменить строку:

current=list_insert_after(current, (void*)temp);

На

current=list_insert_after(current, strdup(mystring));
1 голос
/ 01 февраля 2011

Подумайте об этом - у вас есть временный массив символов в стеке, который разрушается при выходе из области (из блока else), и вы вставляете указатель на этот массив в список. Таким образом, в конце концов список будет иметь указатели на уничтоженные / неверные данные. Поведение не определено.

Вы должны распределять память динамически для каждой строки (и не забывать очищать ее). strdup может быть полезным здесь. Только не забудьте вызвать free при удалении / отбрасывании строки из этого списка.

...