MinGW-w64编译C++链表代码display函数异常,在线GDB运行正常
问题根因
你遇到的不是GCC的bug,是代码中存在未定义行为,不同运行环境对未定义行为的表现差异刚好导致了不同的运行结果:onlinegdb的运行时栈内存未被后续操作覆盖所以能正常执行,MinGW运行时对应栈内存被回收覆写,所以display函数执行异常。
核心错误点
在push函数的首次插入分支(head为NULL的else分支)中:
nodee *first = new nodee(); head = &first;
这里的first是定义在push函数栈帧上的局部指针变量,当push函数执行完成后,该栈帧会被操作系统回收,head存储的是已经失效的栈内存地址,后续在display中访问*head属于非法内存访问,触发未定义行为。
修复方案
首先不需要用二级指针存储头节点,直接将ll类的head成员改为nodee*类型即可,修改后的完整可运行代码如下:
#include <iostream> using namespace std; class nodee { public: int data; nodee *next; }; class ll { public: nodee *head = NULL; // 改为一级指针即可 nodee *push(int no = 1) { nodee *node; int n; if (head != NULL) { node = head; while (node->next != NULL) { node = node->next; } while (no--) { nodee *new_node = new nodee(); cout << "Enter the element : "; cin >> n; node->next = new_node; new_node->data = n; new_node->next = NULL; node = node->next; } } else { nodee *first = new nodee(); head = first; // 直接赋值堆内存地址,不再取局部栈变量的地址 node = head; cout << "Enter the element : "; cin >> n; first->data = n; first->next = NULL; // 补充头节点next的初始化,避免野指针 no--; while (no--) { nodee *new_node = new nodee(); cout << "Enter the element : "; cin >> n; node->next = new_node; new_node->data = n; new_node->next = NULL; node = node->next; } } return head; } void display() { nodee *node = head; while (node->next != NULL) { cout << node->data<<endl; node = node->next; } cout<<node->data<<endl; } }; int main() { ll arr; arr.push(5); arr.display(); return 0; }
额外优化建议
- 可以给
nodee类添加构造函数,简化新建节点时的初始化逻辑,避免出现未初始化的野指针 - 链表使用完后需要手动
delete所有节点,避免内存泄漏 - 建议增加空链表判断,避免空链表状态下调用
display时访问空指针
内容的提问来源于stack exchange,提问作者YashRM
相关产品推荐
相关产品推荐

