二叉树C代码全局指针引发死循环,局部声明为何能修复?
全局指针引发二叉树递归死循环的原因及修复原理
原问题代码(存在死循环)
//binary tree #include<stdio.h> #include<stdlib.h> struct node { int data; struct node* lc; struct node* rc; }*ptr,*root; void preorder(struct node* root){ if(root!=NULL){ printf("%d ",root->data); preorder(root->lc); preorder(root->rc); } } struct node* create(){ int x; ptr = (struct node*)malloc(sizeof( struct node )); printf("type data value(enter -1 if not needed):\n"); scanf("%d",&x); if(x!=-1){ ptr->data = x; printf("Left child of %d:\n",x); ptr->lc = create(); printf("Right child of %d:\n",x); ptr->rc = create(); return ptr; } else{ return NULL; } } void main(){ root = NULL; root = create(); preorder(root); }
修改后正常运行的关键片段
struct node* create(){ int x; struct node* ptr = (struct node*)malloc(sizeof( struct node )); // 后续逻辑不变 ....... void main(){ struct node* root = NULL; // 后续逻辑不变 }
全局指针引发死循环的原因
全局变量ptr在整个程序中只有一份内存空间,递归调用create()时会反复覆盖它的值:
- 假设正在创建节点A,执行到
ptr->lc = create()时,递归进入create()为节点A的左子节点分配内存,此时全局ptr被更新为左子节点的地址。 - 如果输入-1表示左子节点不存在,递归返回
NULL,此时节点A的lc被设为NULL,但全局ptr已经变成了那个被分配但要丢弃的节点地址。 - 回到节点A的逻辑,接下来执行
ptr->rc = create(),这里的ptr已经不是节点A的地址了,而是刚才那个废弃节点的地址。后续递归操作会基于这个错误的指针继续执行,导致节点的左右子指针被错误赋值,最终形成循环引用或者无限递归调用,触发死循环。
局部指针修复问题的原理
把ptr声明为create()函数的局部变量后:
- 每次递归调用
create(),都会在函数栈帧中生成一个独立的ptr变量,各个递归层级的ptr互不干扰。 - 创建节点A时,当前层级的
ptr指向节点A的内存;递归创建左子节点时,子层级有自己的ptr,不会修改节点A层级的ptr。 - 从递归返回后,节点A层级的
ptr仍然指向节点A,能正确设置rc指针,整个二叉树的构建逻辑完全符合预期,不会出现指针混乱的情况。
内容的提问来源于stack exchange,提问作者john saju kallachiyil
相关产品推荐
相关产品推荐

