void *的链表

时间:2011-02-01 17:11:39

标签: c gcc linked-list

我正在尝试读取文本文件并将每行存储在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

所有链表功能都经过全面测试,所以我猜问题就是我如何使用它。我想要实现的是每个节点中有一行,而我现在拥有的是每个节点的最后一行。我想这与char指针有关,但已经花了两个小时没有一个壮观的突破,所以也许有人可以帮忙? 我使用的列表也是一个修改过的列表,如here所示。

 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 个答案:

答案 0 :(得分:3)

您正在使用单个数组temp创建每个节点。每次读取一行时,都会将temp的内容替换为您读取的最后一行。这就是为什么你在每个节点上都有最后一行(你指的是每个节点中的相同内存位置)。

你应该做的是使用malloc为每一行动态分配内存。因此,您应该将指向新分配的内存的指针传递给list_insert_after,而不是传递temp。

答案 1 :(得分:1)

想一想 - 你在堆栈上有一个临时的char数组,它在退出范围(else块)时被破坏,你将指向该数组的指针插入到列表中。毕竟,列表最终会指向已销毁/不正确的数据。行为未定义。

您必须为每个字符串动态分配内存(不要忘记清理它)。 strdup在这里很有用。在从该列表中删除/删除字符串时,不要忘记调用free

答案 2 :(得分:1)

删除该行:

strcpy(temp, mystring); 

然后换行:

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

current=list_insert_after(current, strdup(mystring));