【问题标题】:C code to create a linked list segmentation faultC代码创建链表分段错误
【发布时间】:2020-08-14 06:18:09
【问题描述】:

好的,所以对于我的家庭作业,我有一个从文件输入创建链接列表的函数,它就像一个日历,所以它从文件中读取日期和标题。我正在使用一个全局声明的头节点来实现它 更容易使用其他功能。
这是我的节点结构:

typedef struct event_t{  
    char title[20];  
    event_date_t date;  
    struct event_t *next;  
}event_t;

event_date_t 只是一个简单的日期结构 函数如下:

void insert_events_linked_list(FILE *file, int n){
    //printf("LL function started\n"); //self-explanatory test line
    event_t last;
    head.next = &last;
    int i;
    //This loop will create a ll of the specified length
    for(i=0; i<n; i++){
        event_t *last = malloc(sizeof(event_t));
        int title_test = fscanf(file, "%20s%*c", last->title);
        printf("%s\n", last->title); //test line to make sure names are grabbed properly
        //This skips the rest of the event and prints error message if title is too long
        if(title_test != 1){
            fscanf(file, "%*s %*d %*d");
            printf("Error: LL event %d title too long\n", i++);
            continue;
        }
        else{
            fscanf(file, "%d %d", &last->date.month, &last->date.day);
            last = last->next;
        }
    }
    printf("Loop exited");
}

测试行打印所有标题,但在打印“循环退出”之前显示分段错误并中止

【问题讨论】:

  • 当你使用你的调试器时,它说哪一行发生了段错误?
  • 顺便说一句,head.next = &amp;last; 会以糟糕的方式结束。 head 是全局变量,而 last 是局部变量。
  • @Joseph Sible-Reinstate Monica 看起来它正在循环结束后立即发生,有没有办法做一个全局链表?这将使它更容易使用,因为我最终需要使用其他几个函数对这个列表进行更多操作。
  • 关闭 1。使用 char title[20]; ....fscanf(file, "%19s%*c", last-&gt;title);/ 发布示例输入。

标签: c linked-list segmentation-fault


【解决方案1】:

这行代码,

event_t *last = malloc(sizeof(event_t));

将在每次for 循环返回时声明一个全新的last。将其声明为static 并相应地调整您的代码,应该不再有任何问题。

演示

for (i=0;i<5;i++){
    int x=6;
    x++;
    printf("%d ",x);
}

输出

7 7 7 7 7

你应该看到问题了。

【讨论】:

  • 不确定你的意思,我需要它循环为链表中的每个条目创建节点。条目数是我从用户输入中获得的值。
  • 您正在尝试做last=last-&gt;next,但是,由于您的last 的存储类是auto,所以您没有实现您想要的;当进入下一轮 for 循环时,你会得到一个全新的 last 而不是 last-&gt;next 抱歉我的英语不好(非母语人士)
  • 制作laststatic肯定解决不了任何问题。
【解决方案2】:

测试行打印所有标题,但显示分段错误并在打印“循环退出”之前中止

您的程序中有很多错误。你应该阅读this post。您还应该学习使用调试器。

我怀疑Loop exited 未打印的原因是您没有使用换行符终止它,因此printf 正在等待您完成一行或致电fflush。默认情况下,printf 输出是 line 缓冲的。这就是您应该始终改用fprintf(stderr, ...) 的原因之一。 stderr(默认)是无缓冲的。

关于错误。

  1. 在同一个作用域中有两个名为last 的变量。这几乎不是一个好主意。
  2. 此声明:

    head.next = &amp;last;

    local 变量的地址分配给 global head 指针。当前函数返回后,该地址将变为无效,这几乎肯定不是您想要的。特别是,head.next 从不 指向你在循环中malloc(和泄漏!)的任何内存。

  3. 您的循环如下所示:

    for (...) {
      event_t *last = malloc(sizeof(event_t));  // last->next is uninitialized
      ...
      last = last->next;  // leak the memory allocated above 
                          // by overwriting the pointer with garbage
    }
    

    这显然也不是你想要的。

这是一种增量构建链表的方法:

   event_t **link = &head.next;

   for (...) {
     event_t *ev = calloc(...);  // Initializes ev->next to NULL.

     // Fill the rest of ev ...

     // Link it into the list:
     *link = ev;
     link = &ev->next;
   }

【讨论】:

    猜你喜欢
    • 2012-11-19
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多