C使用指针指向第一个节点(头节点)的指针打印单个链表时出现分段故障



目的:创建一个单独的链表,并使用HEAD POINTER(而不是HEAD NODE)打印列表。

**start:

  • 是HEAD NODE (FIRST NODE)指针

  • 不是将HEAD NODE(FIRST NODE)存储为*start,而是将HEAD NODE指针存储为**start

ALG:

  1. 创建五个节点的列表(在我的程序中硬编码)。
  2. 使用指向HEAD NODE的指针显示它们

代码中有一个重要的漏洞,不容易出现。谁能给你的意见吗?

#include <stdio.h>
#include <stdlib.h>
struct node {
        int data;
        struct node *link;
}**start;

void display(void) {
        struct node *p;
        if (!strart ) { printf("List is emptyn"); return; }
        p = *start;
        printf("List :");
        while(p != NULL) {
                printf("-%d", p->data);
                p = p->link;
        }
        puts("");
}
struct node **createlist(void) {
        int n;
        struct node *p, *new, *tmp; 
        printf("enter no of elements to addn");
        //scanf("%d", &n);
        p = NULL;
        n=5;
        while(n--) {
                new = (struct node *) calloc(1, sizeof(struct node)); 
                new->data = n;
                if (p) {
                        p->link = new;
                        p = new;
                } else if (p == NULL) {
                        p = tmp = new;
                }
        }
        printf("before assign start :%pn", start);
        start = &tmp;
        printf("after assign start :%pn", start);
        printf("In create List :n");
        display();
        return start; 
}
int main() {
        int ch;
        do {
                printf("1.CreateList 2.DisplayListn");
                //scanf("%d", &ch); //HARDCODED
                switch(1) {
                        printf("switch -> start :%pn", start);
                        case 1 : start = createlist();
                        printf("after create -> start :%pn", start);
                        case 2 : printf("Disp:n"); display(); break;
                        default : printf("Invalid optionn");
                }
        } while(0);
        return 0;
}

代码输出:

root@CDrive:~/datastructures# ./a.out 
1.CreateList 2.DisplayList
enter no of elements to add
before assign start :(nil)
after assign start :0x7ffd13e64798
In create List :
List :-4-3-2-1-0
after create -> start :0x7ffd13e64798
Disp:
Segmentation fault (core dumped)

在这里,您为start分配了一个临时的、函数局部对象的地址:

   start = &tmp;

之后返回那个地址:

    return start;

从这里返回的指针指向一个不再存在的对象。

我不清楚你为什么把start声明为struct node **。你说:

**start:是HEAD NODE (FIRST NODE)指针

…但事实并非如此。**start是一个节点,而不是指针。可以使*start 指向第一个节点。start被声明为指向节点指针的指针。

不是将HEAD NODE(FIRST NODE)存储为*start,而是将HEAD NODE指针存储为**start

你不能;正如声明的那样,它不是正确的类型。**start是一个节点,你不能在其中存储节点指针。*start是指向节点的指针,start是指向节点的指针。

我真的认为start应该被声明为struct node *而不是struct node **。你似乎误解了双星的意思。

问题出现在这里随着函数createist()的返回,它的堆栈帧被销毁,甚至变量temp也被销毁。因此,temp变量不再存在,并且列表的第一个节点的地址在temp中,因此值*start在main函数中变为零,并且访问元素总是会出现分段错误。

    start = &tmp;
    printf("after assign start :%pn", start);
    printf("In create List :n");
    display();

为了克服这个问题,可以使用全局头指针来保存第一个节点的地址,或者您可以将tmp变量作为全局变量。

相关内容

  • 没有找到相关文章

最新更新