2015-12-19 240 views
0

我试图实现一个函数makelinkedList,它接受链表中的节点数并返回地址。功能printlinkedList打印链接列表。为什么在这个LinkedList实现中出现分段错误

当我实现此代码时,我不会收到分段错误。

#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; 
} 

输出的代码的以上给出: - > 3 - > 2 - > 1 - > 0 -

4> | NULL |

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

#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; 
} 

为什么我不能返回头的地址?

+1

地方(而不是静态)指针变量的地址不是范围的有效之外。 – BLUEPIXY

+1

你的代码的第一个版本很好..没有必要混乱它。尽管你可以传递一个单一深度的指针到'print'。 –

回答

3

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

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

0

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

事实上,你可以简单地通过headprintLinkedList,并简化为ljst取指针而不是指针指针。

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

#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; 
} 
相关问题