【问题标题】:Linked List in C - Segmentation FaultC中的链表 - 分段错误
【发布时间】:2013-10-21 06:44:21
【问题描述】:

我是一个初学者,正在学习如何在 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;

【问题讨论】:

  • 与您的问题无关,但仅供参考,(*foo).bar 形式的任何内容都可以重写为foo->bar。
  • 你检查data是否有一个有效值?

标签: c linked-list segmentation-fault


【解决方案1】:

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

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

【讨论】:

  • 或者只是删除 malloc() 部分,因为这就是搞砸了。然后按原样进入初始化部分。也许除了那个丑陋的(*inList).data 部分。
  • @zubergu:当然。这也是一个有效的解决方案。尽管那时我认为该函数的名称有些错误(create vs init)。
  • 你说的很对。
【解决方案2】:

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

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

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

然后您初始化全新的 LinkedList 结构,从 createEmptyLinkedList() 返回而不更改 main() 中的 list 结构,因为您初始化了新的 malloc'd 结构,不是列表。

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

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

【讨论】:

    猜你喜欢
    • 2012-06-12
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 2020-06-19
    相关资源
    最近更新 更多