C 为什么我会犯错?

C 为什么我会犯错?,c,segmentation-fault,C,Segmentation Fault,当我运行这段代码时,它显示了一个分段错误 我搜索了Stackoverflow上的其他相关帖子,但没有找到答案,也没有找到代码显示此错误的原因 #include <stdio.h> #include <stdlib.h> #include <malloc.h> struct node{ int info; struct node *next; }; typedef struct node NODE; NODE* getNode(); void

当我运行这段代码时,它显示了一个分段错误

我搜索了Stackoverflow上的其他相关帖子,但没有找到答案,也没有找到代码显示此错误的原因

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node{
    int info;
    struct node *next;
};
typedef struct node NODE;


NODE* getNode();
void insertAtFirst(NODE*,int);
void traverse(NODE*);

int main(){
    NODE *start = NULL;
    insertAtFirst(start,1);
    insertAtFirst(start,4);
    traverse(start);
    return 0;
}

void insertAtFirst(NODE *start, int n){
    NODE *p = (NODE*)malloc(sizeof(NODE));
    p->info = n;
    if(start == NULL){
        p->next = NULL;
    }
    else{
        p->next = start;
    }
    start = p;
}

void traverse(NODE *start){
    NODE *temp;
    temp = start;
    while(temp != NULL){
        printf("%d  ", temp->info);
        temp = temp->next;
    }
}
#包括
#包括
#包括
结构节点{
国际信息;
结构节点*下一步;
};
typedef结构节点;
NODE*getNode();
void insertafirst(节点*,int);
空心导线(节点*);
int main(){
NODE*start=NULL;
insertAtFirst(开始,1);
insertfirst(开始,4);
横移(开始);
返回0;
}
void insertafirst(节点*start,int n){
NODE*p=(NODE*)malloc(sizeof(NODE));
p->info=n;
if(start==NULL){
p->next=NULL;
}
否则{
p->next=开始;
}
开始=p;
}
无效遍历(节点*开始){
节点*温度;
温度=启动;
while(temp!=NULL){
printf(“%d”,临时->信息);
温度=温度->下一步;
}
}

请告诉我为什么在运行程序时出现分段错误(核心转储)。

您应该使用所有警告和调试信息进行编译(例如,
gcc-Wall-g
如果使用…)。然后改进代码,使其不再收到警告

然后您应该使用调试器,例如
gdb

我不会更正您的代码,但您需要了解所有参数(包括指针)都是按值传递的。因此,如果将指针传递给某个修改其参数的函数,则原始指针保持不变

您应该花几天时间阅读有关C和编程(以及调试和测试)的好书。您还应该阅读一些现有的源代码,例如一些自由软件项目的源代码

void insertAtFirst(NODE *start, int n){
    NODE *p = malloc(sizeof(NODE));
    p->info = n;
    if(start == NULL){
        p->next = NULL;
    }
    else{
        p->next = start;
    }
    start = p;
}

最后一行
start=p
的作用与您认为的不同,它不会使
main
中的原始指针指向新节点,因为在函数中,
start
是传递到此函数的原始指针的副本。

请使用调试器运行它,以找出分段错误发生的位置您正在将
*start
用作单个指针,但在您使用它的上下文中,它需要是双精度的。另外,您不应该从
malloc
@mia强制转换返回值,这可能不是您的问题,但是:
if(start==NULL)p->next=NULL;else p->next=开始可以减少为
p->next=start不改变行为。如果您不是在
节点中强制转换*start=NULL然后我想问,为什么你要在
NODE*p=(NODE*)malloc(sizeof(NODE))。这应该是对我的代码segfaults的标准答案,几乎是重复的。@dave:并不是家庭作业中的每一个segfaults都是因为对参数传递的误解。一些新手学生能够解决其他类型的问题。但是,是的,每个学生都应该学习调试。我不明白他们的老师为什么不教这个。是的,但你没有告诉这个人为什么这个特殊的代码段出错,你解释了如何找到它!这始终是“为什么这个seg会出错?”的答案,但可能不是在尝试了上述内容之后,对其他一些经过深思熟虑的问题的答案。@dave我们已经有了两篇关于“一般seg错误”的经典帖子。顺便说一句,如果我仍然想从主函数传递“start”,我该怎么办?@mia Check指针到指针的概念。您还可以在google上找到一些使用指向指针的指针的链表实现。@mia您应该声明
insertFirst(节点**start…
(双指针),相应地更改函数,并调用func passing
&start
作为参数。