2

我是一个初学者,正在学习如何在 C 中创建链表。每当我尝试打印出列表时,列表打印得很好,但最后总是会出现分段错误。

当我使用 GDB 回溯时,它指向我的行 -> entry = *((*node).data); 在 printContents 函数中。

但是我不太确定它有什么问题。

下面是链表代码:

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;
4

2 回答 2

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);

请注意,此处列表被声明为指针。

于 2013-10-13T16:59:40.797 回答
2

在我看来,问题是你没有决定是否createEmptyLinkedList()应该为你的头部分配内存,或者你会在main()函数中这样做。
而你两者都做到了。
main()
你做LinkedList list;的 - 这部分创建 LinkedList 结构。
然后将该结构的地址传递给您的函数。这很好。

在您createEmptyLinkedList()的 inList 指针指向列表结构。这也很好。

但是现在你把事情搞砸了,malloc()另一个 LinkedList 结构inList指向新的 malloc 结构。

然后你初始化你全新的 LinkedList 结构,从createEmptyLinkedList()没有改变list结构的情况下返回,main()因为你初始化了你的新malloc'd结构,而不是 list

您可以通过决定您的LinkedList结构是否将在main()或中创建来修复它createEmptyLinkedList()
如果您选择第二个 - 阅读上面的答案。
但是,如果您选择第一个 - 保留所有内容并删除createEmptyLinkedList()负责 malloc'ing 的行。

然后,正如FatalError所建议的那样 - 对您的函数更合适的名称将是initializeEmptyLinkedList因为不再有创建部分。

于 2013-10-13T17:18:59.037 回答