2013-04-28 99 views
0

我的列表頭始終指向尾部。有什麼問題?我無法在C中正確創建雙向鏈接列表

linked_list.h我:

#ifndef LINKED_LIST 
#define LINKED_LIST 

struct node 
{ 
    char *data; 
    struct node *nextElement; 
    struct node *prevElement; 
}; 

void createList(struct node **head, struct node **tail); 
void fill_list (char *word, struct node **head, struct node **tail); 

#endif 

main.c

#include <stdio.h> 
#include <stdlib.h> 
#include "linked_list.h" 
#include <string.h> 

int main() 
{ 
    FILE *dataFile; 
    char *word = (char *) calloc (255, sizeof(char)); 

/* Create empty list */ 
    struct node *head, *tail;  
    createList (&head, &tail); 
/*------------------------*/ 

/* Data file open*/ 
    dataFile = fopen("data.txt" ,"r"); 
    if(dataFile == NULL) 
    { 
     perror("Error while opening the file.\n"); 
     exit(EXIT_FAILURE); 
    } 

/* Data reading */ 
    while ((fscanf(dataFile, "%s", word)) != EOF) 
    { 
     int i   = 0; 
     int wordsCount = 0; 

     for (i = 0; i <= strlen(word); i++) 
     { 
     if ((word[i] >= 'a') && (word[i] <= 'z')) 
      wordsCount = wordsCount + 1; 
     } 

     if (wordsCount == strlen(word)) 
     { 
     fill_list (word, &head, &tail); 
     }  
    } 

    fclose(dataFile); 
    return 0; 
}; 

linked_list.c

#include <stdio.h> 
#include <stdlib.h> 
#include "linked_list.h" 

void createList(struct node **head, struct node **tail) 
{ 
    *head = NULL; 
    *tail = NULL; 
} 

void fill_list (char *word,  struct node **head,  struct node **tail) 
{ 
    struct node *elem, *temp; 

    if ((*head) == NULL) 
    { 
    // printf("HEAD = NULL\n"); 

     elem = (struct node *) malloc (sizeof (struct node)); 
     elem -> data = word; 
     elem -> nextElement = NULL; 
     elem -> prevElement = NULL; 
     (*head) = elem; 
     *tail = elem; 
    // printf("%s\n", (*head) -> data );   
    } 
    else 
    { 
    // printf("HEAD != NULL\n"); 
     elem = (struct node *) malloc (sizeof (struct node)); 
     elem -> data = word; 
     elem -> nextElement = NULL; 
     elem -> prevElement = *tail; 
     *tail = elem; 
    // printf("%s\n", (*head) -> data );   
    } 
} 

我的數據文件:QW erty B CC。 首先,head == NULL,所以head -> data = 'qw'它應該始終保持領先,但它會變爲erty,然後在每個循環步驟後變爲b和cc。

我在做什麼錯了?

+0

你是不是要確保舊的最後一個元素指向新的最後一個元素,當你的元素添加到列表中。 – 2013-04-28 18:09:35

回答

3

問題是,您對所有輸入使用相同的字符串,並將其用於所有節點。這意味着所有的節點將其data成員指向相同的字符串。這個字符串當然只包含你上次讀入的內容。

您可能希望將main中的字符串緩衝區保存爲普通數組(而不是將其分配到堆中)並使用strdup複製節點的字符串。不要忘記以後再解放他們。


指針正是這聽起來像,這是一個變量,它在內存其他一些地方。你可以有許多指針指向同一個內存。

在您的情況下,您將功能main中的指針word傳遞給fill_list的所有調用。這意味着您在fill_list中創建的所有節點將使用完全相同的指針,並且它們都指向完全相同的內存。

這意味着,在列表中的所有節點都將有data成員似乎是相同的值,它總是會在main函數讀入word最後一個字符串。

如果您使用的功能如strdup那麼會重複這個字符串。即它會爲該字符串分配全新的內存並從舊區域複製到新分配的區域,並返回一個指向新分配的內存的指針。

+0

你能詳細解釋一下嗎? 我不明白你的意思。 – Pauliuks 2013-04-28 18:21:59

+0

@Pauliuks詳細闡述了一下。 – 2013-04-28 18:37:00

+0

好吧,現在主要的問題是如何使用strdup。 我應該在哪裏以及如何使用它?對於愚蠢的問題抱歉,但也許它不需要很多時間給你。 – Pauliuks 2013-04-28 18:59:58

1

試試這個

void fill_list (char *word,  struct node **head,  struct node **tail) 
    { 
     struct node *elem, *temp; 

     /* you need to create node first ! */ 
     elem = (struct node *) malloc (sizeof (struct node)); 
     elem -> data = NULL ; 
     elem -> data = (char*) malloc(sizeof(char)*255)); 
     if (elem -> data == NULL) 
      { 
      perror("alloc data failed "); 

      } 

     if ((*head) == NULL) 
     { 
     // printf("HEAD = NULL\n"); 
    /* call memcpy() function need to #include <string.h> */ 

      elem -> data = memcpy((void*)elem -> data,(void*)word,strlen(word)); 
      elem -> nextElement = NULL; 
      elem -> prevElement = NULL; 
      (*head) = elem; 
      *tail = elem; 
     // printf("%s\n", (*head) -> data );   
     } 
     else 
     { 
     // printf("HEAD != NULL\n"); 

      elem -> data = memcpy((void*)elem -> data,(void*)word,strlen(word)); 
      elem -> nextElement = NULL; 
      elem -> prevElement = *tail; 
      *tail = elem; 
     // printf("%s\n", (*head) -> data );   
     } 
+0

程序崩潰後: /*爲每個節點分配*/ elem - > data =(char *)malloc(sizeof(char)* 255); – Pauliuks 2013-04-28 18:40:34