2013-10-13 66 views
1

我是一個初學者,學習如何在C中創建鏈表。每當我嘗試打印出列表時,列表打印出來就好,但我總是以分段錯誤結束結束。當我使用GDB回溯時,它指向了行 - > entry = *((* node).data);在printContents函數中。C中的鏈接列表 - 分段錯誤

但是我不太清楚它有什麼問題。

這裏是鏈表代碼:

void createEmptyLinkedList(LinkedList *inList) { 
    inList = (LinkedList*)malloc(sizeof(LinkedList)); 

    (*inList).head = NULL; 
    (*inList).tail = NULL; 

    (*inList).size = 0; //Keeps track of size of list 

    return; 
} 
void insertAtStart(LinkedList *inList, JournalEntry *inValue) { 
    LinkedListNode *newNode; 
    int listSize = (*inList).size; 

    newNode = (LinkedListNode*)malloc(sizeof(LinkedListNode)); 

    (*newNode).data = inValue; 
    (*newNode).next = (*inList).head; 
    (*inList).head = newNode; 
    ((*inList).size)++; 
    return; 
} 

void printContents(LinkedList *inList) { 
    LinkedListNode *node; 
    JournalEntry entry; 

    node = (*inList).head; 

    while (node != NULL) { 

      entry = *((*node).data); 

      printf("%04d-%02d-%02d: %s\n", entry.year, entry.month, entry.day, entry.text); 

      /*Move node to the next node*/ 
      node = (*node).next; 
    } 
    printf("Done!"); 
    return; 
} 
//Free nodes recursively 
void freeLinkedList(LinkedList *inList) { 
    freeNode((*inList).head); 
    free(inList); 
    return; 
} 

void freeNode(LinkedListNode *node) { 
    if (node != NULL) { 
    freeNode((*node).next); 
    free(node); 
} 

這裏是用來啓動鏈表的主要功能:

int main() { 
    LinkedList list; 
    JournalEntry *value; 
    char* textToEnter; 

    value = (JournalEntry*)malloc(sizeof(JournalEntry)); 

    createEmptyLinkedList(&list); 

    textToEnter = "Hello"; 
    (*value).day = 10; 
    (*value).month = 5; 
    (*value).year = 2010; 
    strcpy((*value).text, textToEnter); 
    insertAtStart(&list, value); 

    printContents(&list); 

    freeLinkedList(&list); 
    return 0; 
} 

以防萬一有人需要它,下面是聲明的結構在頭文件中:

typedef struct LinkedListNode { 
    JournalEntry *data; 
    struct LinkedListNode *next; 
} LinkedListNode; 
typedef struct { 
    LinkedListNode *head; 
    LinkedListNode *tail; 
    int size; 
} LinkedList; 
typedef struct { 
    int day; 
    int month; 
    int year; 
    char text[1000]; 
} JournalEntry; 
+6

與您的問題沒有特別的關係,但僅供將來參考,「(* foo).bar」形式的任何內容都可以重寫爲「foo-> bar」。 –

+0

您是否檢查'data'是否有有效值? – jxh

回答

7

C中的所有內容都按值傳遞,包括指針。所以,分配給inList不會影響調用者傳遞的值。相反,你應該考慮一個指針的指針,如果你想要做這種方式:

void createEmptyLinkedList(LinkedList **inList) { 
    *inList = malloc(sizeof(LinkedList)); 

    (*inList)->head = NULL; 
    (*inList)->tail = NULL; 

    (*inList)->size = 0; //Keeps track of size of list 

    return; 
} 

如果沒有這個,你只是一個未初始化的指針來保存你的工作清單。在您的主代碼中,您還需要將其更改爲:

LinkedList *list; 
createEmptyLinkedList(&list); 

請注意,列表在這裏被聲明爲指針。

+0

或者只是刪除malloc()部分,因爲這就是搞砸了。然後按照它的方式去初始化部分。也許除了醜陋的'(* inList).data'部分。 – zubergu

+0

@zubergu:當然。這也是一個有效的解決方案。雖然在那一點上我會爭論這個函數有些錯誤(創建vs init)。 – FatalError

+0

你是絕對正確的。 – zubergu

2

我看到它的方式,問題是你沒有決定是否createEmptyLinkedList()應該爲你的頭部分配內存,或者你會在main()函數中做到這一點。
你們都做到了。
main()
你做了LinkedList list; - 這部分創建LinkedList結構。
然後,您將該結構的地址傳遞給您的函數。這點很好。

在你的createEmptyLinkedList()你有inList指針指向列表結構。這也很好。

但是現在你搞砸了另外一個LinkedList結構,並且inList指向新建malloc'd結構。

然後初始化全新的鏈表結構,從createEmptyLinkedList()返回而不main()改變list結構,因爲你初始化你的新malloc'd結構,沒有列出

您可以通過決定是否在main()createEmptyLinkedList()中創建LinkedList結構來解決此問題。
如果您選擇2nd - 請閱讀以上答案。
但是,如果您選擇1st - 將所有內容保留原樣,並且刪除負責malloc'ing的createEmptyLinkedList()中的行。

然後,FatalError建議 - 更多appriopriate名字給你的函數將initializeEmptyLinkedList因爲沒有了創建一部分。