C语言双向链表代码编译无错返回3221225477无输出如何解决
问题原因分析
返回值3221225477是Windows平台下的内存访问违规错误(等价于Linux系统的段错误),本质是代码触发了空指针解引用,操作系统直接终止进程,输出缓冲区的内容还没来得及刷新到控制台就退出,因此没有任何打印内容。编译阶段不会检查空指针访问这类运行时错误,所以不会报错。
具体问题点如下:
- 插入函数无空指针判断
初始状态下头节点的left和right都为NULL,第一次调用insert_left时,执行p->left->right = new_node就是对空指针解引用,直接触发崩溃;insert_right第一次调用时同理,p->right->left = new_node也是空指针访问。 - 移动函数是值传递,修改不生效
move_left和move_right的指针参数是值传递,函数内部修改指针p的指向,不会影响外部实参的指向,移动操作完全无效。 - 删除函数也存在空指针风险
如果要删除的节点是链表尾节点,p->right->right为NULL,执行p->right->right->left = p同样会触发空指针解引用;且现有代码没有释放被删除节点的内存,存在内存泄漏。
修复代码示例
#include <stdio.h> #include <stdlib.h> //定义节点 typedef struct ListNode { int val; struct ListNode* left; struct ListNode* right; } ListNode; //右侧插入节点 void insert_right(ListNode* p) { ListNode* new_node = (ListNode*)malloc(sizeof(ListNode)); new_node->val = 0; new_node->left = p; new_node->right = p->right; //原右节点存在时才修改它的左指针 if(p->right != NULL) { p->right->left = new_node; } p->right = new_node; } //左侧插入节点 void insert_left(ListNode* p) { ListNode* new_node = (ListNode*)malloc(sizeof(ListNode)); new_node->val = 0; new_node->right = p; new_node->left = p->left; //原左节点存在时才修改它的右指针 if(p->left != NULL) { p->left->right = new_node; } p->left = new_node; } //向右移动X步,返回移动后的指针 ListNode* move_right(int X, ListNode* p) { int i; for(i = 0; i < X; i++) { if (p->right != NULL) { p = p->right; } else { printf("Right"); break; } } return p; } //向左移动X步,返回移动后的指针 ListNode* move_left(int X, ListNode* p) { int i; for(i = 0; i < X; i++) { if (p->left != NULL) { p = p->left; } else { printf("Left"); break; } } return p; } //删除p右侧的节点 void remove_right(ListNode* p) { if(p->right != NULL) { ListNode* del = p->right; p->right = del->right; if(del->right != NULL) { del->right->left = p; } free(del); } else printf("Right"); } //删除p左侧的节点 void remove_left(ListNode* p) { if(p->left != NULL) { ListNode* del = p->left; p->left = del->left; if(del->left != NULL) { del->left->right = p; } free(del); } else printf("Left"); } //设置p指向节点的val为X void set(int X, ListNode* p) { p->val = X; } //打印p指向节点的val void show(ListNode* p) { printf("%d", p->val); } int main() { int i, j; //创建头节点 ListNode* head = (ListNode*)malloc(sizeof(ListNode)); head->val = 0; head->left = NULL; head->right = NULL; ListNode* p = head; for(i = 0; i < 6; i++) { insert_left(p); } for(i = 0; i < 6; i++) { insert_right(p); } //接收返回值更新p的指向 p = move_left(2, p); p = move_right(30, p); show(p); printf("ha"); //实际使用时记得遍历释放整个链表的内存 return 0; }
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

