链表头插程序在Eclipse/Dev-C++崩溃,在线编译器运行正常求助
问题分析与修复方案
兄弟,你的代码崩溃的核心原因是未初始化的二级指针导致的野指针解引用,咱们一步步说清楚:
问题出在哪?
在main函数里,你声明了struct list ** ptrptr;,这是一个二级指针,但你没有给它赋值——它现在是个野指针,指向的内存地址完全是随机的。当你把它传给init函数后,init里执行*ptrptr = NULL,本质是在往一块随机的内存区域写数据,这直接触发了未定义行为(也就是Windows下的崩溃)。
至于在线编译器没崩溃,纯粹是运气好——有些在线环境会自动初始化栈内存为0,刚好让这个野指针指向了一块可写的区域,但这绝对不是代码没问题,只是没触发错误而已。
怎么修复?
咱们需要维护的是链表的头指针(一级指针),二级指针只是用来修改这个头指针的。所以正确的做法是在main里声明一个一级指针,然后把它的地址传给相关函数:
#include <stdio.h> #include <stdlib.h> struct list { float value; struct list * next_ptr; }; void init (struct list **ptrptr); void pre_insert(struct list **ptrptr, float value); void visit(struct list * ptr); int main() { // 声明一级指针作为链表头,初始化为NULL(也可以靠init来初始化) struct list *head = NULL; // 传入head的地址,让函数能修改它 init (&head); float value_1 = 47.2; float value_2 = 13.23; float value_3 = 3.4; pre_insert(&head, value_1); pre_insert(&head, value_2); pre_insert(&head, value_3); visit(head); return 0; } void init (struct list** ptrptr){ *ptrptr=NULL; } void pre_insert(struct list ** ptrptr, float value){ struct list * tmp_ptr = *ptrptr; *ptrptr = (struct list *)malloc(sizeof(struct list)); (*ptrptr)->value=value; (*ptrptr)->next_ptr=tmp_ptr; } void visit(struct list * ptr) { while(ptr!= NULL){ printf ("(%f)\n",ptr->value); ptr = ptr->next_ptr; } printf("\n"); }
修复逻辑说明
- 现在
main里的head是链表的头指针(一级指针),我们把它的地址&head传给init和pre_insert,这时候函数里的ptrptr指向的是head变量本身,解引用*ptrptr就是直接操作head,完全合法。 init函数里的*ptrptr = NULL就是把head设为NULL,正确初始化链表为空。- 后续的
pre_insert也能正确修改head的值,把新节点插在链表头部。
这样修改后,不管是MinGW GCC还是其他编译器,都能稳定运行了。
内容的提问来源于stack exchange,提问作者Giuliano Bellucci
相关产品推荐
相关产品推荐

