C语言递归创建链表遇Segmentation fault错误,寻求技术帮助
排查并修复你的C语言链表段错误问题
首先,你的代码出现段错误(Segmentation Fault)主要有两个核心原因,同时还有一个逻辑问题导致输出顺序不符合预期,我逐一给你拆解:
1. 内存分配的两个致命错误
错误1:struct data的内存分配大小错误
在main函数里,你写了:
struct data *d= malloc(sizeof(struct data *));
这里你分配的是指针的大小(32位系统是4字节,64位是8字节),但struct data包含一个指针和一个int,大小远大于指针。这会导致后续访问d->total和d->list时,访问的是超出分配范围的内存,直接触发内存越界,引发段错误。
正确的写法应该是分配整个struct data结构体的大小:
struct data *d= malloc(sizeof(struct data));
错误2:struct listOfNodes未分配内存
你把d->list初始化为NULL,但在addNode函数里直接访问o->list->root——对空指针进行解引用(dereference)是C语言中典型的段错误触发点。你需要先为struct listOfNodes分配内存,并且初始化它的root指针为NULL:
d->list = malloc(sizeof(struct listOfNodes)); d->list->root = NULL;
2. 链表插入逻辑错误(输出顺序不符合预期)
你预期输出是9、8、7……0,但当前的插入逻辑是把新节点插在root的next位置,最终链表顺序是0→1→2→…→9。要实现倒序输出,应该用头插法:每次把新节点作为新的链表头部,这样新节点永远在最前面,最终链表顺序就是9→8→…→0。
修改addNode里的插入代码:
// 替换原来的else块代码 n->next = o->list->root; // 新节点的next指向当前链表的头部 o->list->root = n; // 把新节点设为链表的新头部
完整修正后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> //node struct node { int value; struct node *next; }; //linked list struct listOfNodes { struct node *root; }; //list of parameters to send to the function to print nodes struct data { struct listOfNodes *list; int total; }; void printNode(struct listOfNodes *list) { struct node *n = list->root; while(n!=NULL){ printf("%d\n",n->value); n=n->next; } } void addNode(void* d){ //parameter needs to be a void* struct data *o = (struct data *)d ; if(o->total < 10) { //create new node struct node *n = malloc(sizeof(struct node)); n->value = o->total; n->next = NULL; o->total = o->total + 1; // 头插法实现倒序链表 n->next = o->list->root; o->list->root = n; addNode(d); } } int main() { // 修正:分配整个struct data的大小 struct data *d= malloc(sizeof(struct data)); d->total=0; // 修正:为list分配内存并初始化root为NULL d->list= malloc(sizeof(struct listOfNodes)); d->list->root = NULL; addNode(d); //add recursively 10 times if(d->list!=NULL) printNode(d->list); // 额外建议:记得释放内存,避免内存泄漏 struct node *temp; while(d->list->root != NULL) { temp = d->list->root; d->list->root = d->list->root->next; free(temp); } free(d->list); free(d); return 0; }
额外建议
我在修正后的代码里加了内存释放的逻辑,避免内存泄漏——虽然对于小程序来说影响不大,但养成好习惯很重要。
内容的提问来源于stack exchange,提问作者zancudo
相关产品推荐
相关产品推荐

