You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二叉树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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 05:12:40