【问题标题】:why do get a segmentation fault in this implementation of LinkedList [duplicate]为什么在 LinkedList 的这个实现中会出现分段错误 [重复]
【发布时间】:2015-12-19 08:32:35
【问题描述】:

我正在尝试实现一个函数makelinkedList,它接受链表中的节点数并返回 .函数printlinkedList打印链表。

我在实现此代码时没有遇到分段错误。

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

struct node{
    int data;
    struct node* next;
};

typedef struct node linkedList;

void printlinkedList(linkedList** head){
    linkedList* crawler = *head;

    while(crawler!=NULL){
        printf("%d -> ", crawler->data);
        crawler= crawler->next;
    }
    printf("|NULL|\n");
}

linkedList* makelinkedList(int size){

    linkedList* crawler = malloc(sizeof(linkedList));
    crawler->data = --size;
    crawler->next = NULL;
    linkedList* head = crawler;
    while(size > 0){
        crawler->next = malloc(sizeof(linkedList));
        crawler = crawler->next;
        crawler->data = --size;
        crawler->next = NULL;
    }
    printlinkedList(&head);
    return head;
}

int main(void) {
    // your code goes here
    linkedList* node = (makelinkedList(5));
    linkedList** head = &node;
    printf("from main\n");
    printlinkedList(head);
    return 0;
}

上面给出的代码的输出:

4 -> 3 -> 2 -> 1 -> 0 -> |NULL|

但是当我尝试返回 head (&head) 的地址时,我遇到了分段错误。导致错误的代码如下:

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

struct node{
    int data;
    struct node* next;
};

typedef struct node linkedList;

void printlinkedList(linkedList** head){
    linkedList* crawler = *head;

    while(crawler!=NULL){
        printf("%d -> ", crawler->data);
        crawler= crawler->next;
    }
    printf("|NULL|\n");
}

linkedList** makelinkedList(int size){

    linkedList* crawler = malloc(sizeof(linkedList));
    crawler->data = --size;
    crawler->next = NULL;
    linkedList* head = crawler;
    while(size > 0){
        crawler->next = malloc(sizeof(linkedList));
        crawler = crawler->next;
        crawler->data = --size;
        crawler->next = NULL;
    }

    return &head;
}

int main(void) {
    // your code goes here
    linkedList** head = (makelinkedList(5));
    printf("from main\n");
    printlinkedList(head);
    return 0;
}

为什么不能返回头部地址?

【问题讨论】:

  • 本地(而非静态)指针变量的地址在范围外无效。
  • 你的代码的第一个版本很好..没必要弄乱它。不过,您可以将单深度指针传递给print

标签: c pointers linked-list segmentation-fault


【解决方案1】:

head 是一个局部变量。局部变量在包含它们的函数返回时被销毁。

所以在makelinkedList 返回后,您的“指向head 的指针”不再指向head,因为它不存在。通常,局部变量一旦被销毁就会很快被覆盖,因为 所有 局部变量共享内存中的相同空间(“堆栈”)。当您尝试使用指向head 的指针时,该空间不再包含head 包含的内容,而是已被重新用于存储其他内容。

【讨论】:

    【解决方案2】:

    正如 immibis 在他的回答中解释的那样,您不能返回局部变量的地址。但好消息是您不需要返回地址,只需返回 head 的值即可。 head 是指向列表第一个元素的指针,它携带了所有需要的信息。

    实际上,您也可以将head 传递给printLinkedList,然后将其简化为使用指针而不是指向指针的指针。

    造成混淆的真正原因是typedef struct node linkedList。 linkedList 实际上应该只是指向第一个节点的指针,但类型定义指针类型更加令人困惑。您可以使用更简单的 typedef 并在所有函数中使用指向节点的指针:

    #include <stdio.h>
    #include <stdlib.h>
    
    struct node {
        int data;
        struct node *next;
    };
    
    typedef struct node node;
    
    void printlinkedList(node *head) {
        node *crawler = head;
    
        while (crawler != NULL) {
            printf("%d -> ", crawler->data);
            crawler = crawler->next;
        }
        printf("|NULL|\n");
    }
    
    node *makelinkedList(int size) {        
        node *crawler = malloc(sizeof(node));
        crawler->data = --size;
        crawler->next = NULL;
        mode *head = crawler;
        while (size > 0) {
            crawler->next = malloc(sizeof(linkedList));
            crawler = crawler->next;
            crawler->data = --size;
            crawler->next = NULL;
        }       
        return head;
    }
    
    int main(void) {
        node *head = makelinkedList(5);
        printf("from main\n");
        printlinkedList(head);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-17
      • 2021-09-08
      • 1970-01-01
      • 2013-01-29
      • 2010-10-19
      • 2013-03-28
      相关资源
      最近更新 更多