链表-C-分段错误



我正试图弄清楚为什么我的程序在调用ll_print时会崩溃。[[这是一个非常简单明了的问题,我不确定该添加什么来填补解释空白]]

    struct ll{
          struct ll* next;
          int n;
        } ll;
   void ll_print(struct ll *l){
      while (l) {
        printf("%d ", l->n);
        l=l->next;
      }
    }
    void ll_fill(struct ll *l, int n){
      struct ll *temp= NULL;
       while (n>0){
        l= (struct ll*)malloc(sizeof(struct ll));
        l->n=n;
        l->next= temp;
        temp=l;
        n--;
      }
     }
    int main(void){
      int i=0;
      struct ll *l;                                                                                                                                          
      ll_fill(l, 10);
      ll_print(l);  /** causing a segmntation fault **/                                                                                                                                                                 
    }
这是因为l指针从未初始化。似乎您希望ll_fill初始化它,但您错了——它是按值传递的(按副本读取),并且无论您在ll_fill函数中为l赋值,都不会为main中声明的l赋值。为了实现您想要的,通过指针传递l(您将有一个指向指针的指针)。或者,将其设为ll_fill的返回值,然后执行l = ll_fill(l, 10);。另外,给自己找一个调试器,它会对你有很大帮助。

您没有在main()函数中填充指向局部变量l的指针。相反,您正在ll_fill()函数中填充l的参数。考虑让ll_fill返回malloc'ed指针的值。

当您调用ll_fill(l, 10);时,问问自己,l的值是多少?当然,您在被调用的函数中创建了一个新对象,但您的main()是如何知道这个新对象的?它仍然指向最初(随机)分配给本地变量l未初始化内存。

尝试将NULL作为初始值分配给l:

struct ll *l = NULL;

您只是对byy值调用的概念感到困惑。您正在通过传递值将指针传递给函数ll fill。但ll fill将制作自己的副本,无论它做什么更改,都不会对主函数的指针产生任何影响。因此,当您将其传递给ll_print()时,由于它没有初始化,因此打印该值只会导致分段错误
使用调试器,它将帮助您始终处于这种状态。

更改ll_fill函数定义并调用如下:

void ll_fill(struct ll **l, int n){
  struct ll *temp= NULL;
  while (n>0){
    *l= (struct ll*)malloc(sizeof(struct ll));
    (*l)->n=n;
    (*l)->next= temp;
    temp=(*l);
    n--;
  }
}
int main(void){
  int i=0;
  struct ll *l;                                                                 
  ll_fill(&l, 10);
  ll_print(l);  /** now no segmntation fault :) **/                             
}

由于在函数内为指针l分配内存,因此需要传递指针的地址,而不是传递指针变量。尽管指针l在函数ll_fill内被初始化,但当作用域从函数中出来时,作用域将死亡,并且ll_print(l)由于找不到指针l的地址而抛出segfault。

解决方案:

  1. 如果要在函数内部进行初始化,请传递指针的地址。

  2. 如果指针由多个指针共享,那么最好在两个函数的公共范围内声明(即在main()内初始化)

最新更新