我正试图弄清楚为什么我的程序在调用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。
解决方案:
如果要在函数内部进行初始化,请传递指针的地址。
如果指针由多个指针共享,那么最好在两个函数的公共范围内声明(即在
main()
内初始化)