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

C语言中!temp、!temp->left的含义及二叉树内存释放代码疑问

关于二叉搜索树内存释放代码的疑问解答

1. !temp 是否等价于 temp == NULL?

是完全等价的。在C语言中,指针被当作布尔值使用时,非空指针会被视为真(非0值),空指针(NULL)会被视为假(0值)。! 是逻辑非运算符,对假值取反得到真值,对真值取反得到假值。所以:

  • 当 temp 是 NULL 时,!temp 结果为真,temp == NULL 结果也为真;
  • 当 temp 非空时,!temp 结果为假,temp == NULL 结果也为假。

2. !temp->left 和 !temp->right 是否表示子节点指针为NULL?

是的,原理和上面一致。temp->left 是指向左子节点的指针,当该指针为 NULL 时,!temp->left 结果为真;反之则为假,所以这两个表达式就是判断对应子节点指针是否为空。

3. 代码整体逻辑分析(含问题指出)

这段代码试图用后序遍历的方式释放二叉树内存,但存在严重的内存泄漏bug,逻辑拆解如下:

  • 首先判断传入的节点是否为空,为空则直接返回(递归终止条件);
  • 递归调用释放左子树,再递归释放右子树;
  • 仅当当前节点是叶子节点(左右子节点都为NULL)时,才释放当前节点。

问题核心:

递归释放子树后,当前节点的left/right指针并不会自动变为NULL——它们依然指向已经被释放的内存(野指针),导致!temp->left && !temp->right的判断几乎永远为假(除了原本就是叶子的节点)。最终所有非叶子节点的内存都不会被释放,造成内存泄漏。

正确的后序释放逻辑:

不需要判断是否为叶子节点,递归完成左右子树释放后,直接释放当前节点即可:

void free_tree(Node* root) {
    if (!root)
        return;
    free_tree(root->left);
    free_tree(root->right);
    free(root);
}

后序遍历的特性保证了父节点会在所有子节点释放完成后再被释放,不会出现悬空指针的问题。

内容的提问来源于stack exchange,提问作者lectheeth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:10:53