为什么链表实现多项式运算的C代码在线编译器正常VSCode运行失败
问题根因
你的代码能在Online GDB运行、在VS Code运行失败,本质是未初始化malloc分配的节点的next指针触发的未定义行为:
- Online GDB的编译器默认会将新分配的堆内存清零,你未赋值的next指针刚好被置为NULL,碰巧符合链表遍历的终止条件,所以能正常运行
- VS Code使用的MinGW/MSVC编译器不会对malloc分配的内存做初始化,next指针是随机野值,遍历链表时访问野指针直接触发段错误
具体修复点
- 补全
create_list函数的尾节点初始化
你创建完所有节点后没有将最后一个节点的next置为NULL,修改如下:
node *create_list() { node *head = (node*) malloc(sizeof(node)); int n; int data, power; printf("For node 1:\n"); printf("Enter coefficient: "); scanf("%d", &data); printf("Enter power: "); scanf("%d", &power); node *new_node = (node*) malloc(sizeof(node)); new_node -> data = data; new_node -> power = power; head = new_node; for(n = 0; n < NODES - 1; n++) { printf("For node %d:\n", n+2); printf("Enter coefficient: "); scanf("%d", &data); printf("Enter power: "); scanf("%d", &power); node *new = (node*) malloc(sizeof(node)); new -> data = data; new -> power = power; new_node -> next = new; new_node = new; } // 新增:尾节点next置空 new_node->next = NULL; return head; }
- 所有创建哨兵头节点的位置,初始化next为NULL
你在simplify、add、multiply中通过malloc创建的临时头节点,都需要立刻初始化next为NULL,举个例子:
// simplify函数中修改 node *output = (node*) malloc(sizeof(node)); output->next = NULL; // 新增初始化 // add函数中修改 node *head3 = (node*) malloc(sizeof(node)); head3->next = NULL; // 新增初始化 // multiply函数中修改 node *head3 = (node*) malloc(sizeof(node)); head3->next = NULL; // 新增初始化
- 可选优化:给display函数加空指针判断
避免传入空链表时直接访问野指针:
void display(node *head) { if(head == NULL) { printf("0\n"); return; } while(head -> next != NULL) { printf("%dx^(%d) + ", head-> data, head -> power); head = head -> next; } printf("%dx^(%d)\n", head -> data, head -> power); }
完成以上修改后,代码在VS Code环境就能正常运行。
内容的提问来源于stack exchange,提问作者Pramit Bhatia
相关产品推荐
相关产品推荐

