【问题标题】:C segmentation fault when printing single linked list using pointer to pointer of first node(head node)使用指向第一个节点(头节点)指针的指针打印单个链表时出现 C 分段错误
【发布时间】:2016-10-19 10:15:30
【问题描述】:

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

**start:

  • 是HEAD NODE(FIRST NODE)指针

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

算法:

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

代码中有一个明显的HOLE,不容易出现。 任何人都可以就此提供您的意见。

#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 empty\n"); 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 add\n");
        //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 :%p\n", start);
        start = &tmp;
        printf("after assign start :%p\n", start);
        printf("In create List :\n");
        display();

        return start; 
}
int main() {

        int ch;
        do {
                printf("1.CreateList 2.DisplayList\n");
                //scanf("%d", &ch); //HARDCODED

                switch(1) {
                        printf("switch -> start :%p\n", start);
                        case 1 : start = createlist();
                        printf("after create -> start :%p\n", start);
                        case 2 : printf("Disp:\n"); display(); break;
                        default : printf("Invalid option\n");
                }
        } 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)

【问题讨论】:

  • 使用valgrind
  • 使用调试器。
  • struct node **createlist(void) 返回一个指向指针的指针在这里没什么意义。

标签: c pointers linked-list


【解决方案1】:

在这里,您为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 **。您似乎误解了双星的含义。

【讨论】:

    【解决方案2】:

    问题出现在这里 随着函数 createlist() 的返回,它的堆栈帧被破坏,甚至变量 temp 也被破坏。所以 temp 变量不再存在,我们有 list 的第一个节点的地址在 temp 中,所以值 *start 在 main 函数中变为零并且访问元素总是存在分段错误。

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

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

    【讨论】:

      猜你喜欢
      • 2014-12-13
      • 2021-02-19
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      相关资源
      最近更新 更多