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
相关产品推荐
相关产品推荐

