编写二叉树通用释放函数时gcc报无限递归,求报错原因
二叉树释放函数的无限递归编译错误问题
我尝试编写一个二叉树的通用释放函数,相关代码如下:
结构体定义
typedef struct s_tree { void *content; struct s_tree *left; struct s_tree *right; } t_tree;
释放函数实现
void ft_treeclear(t_tree **tree, void (*del)(void*)) { ft_treeclear(&((*tree)->left), del); ft_treeclear(&((*tree)->right), del); del((*tree)->content); free((*tree)); *tree = NULL; }
使用-Wextra -Werror -Wall编译选项时,编译器报出无限递归错误:
gcc -Wextra -Werror -Wall -c -o obj/main.o code/main.c -Ilibft -Ihead gcc -Wextra -Werror -Wall -c -o obj/parse_tree.o code/parse_tree.c -Ilibft -Ihead code/parse_tree.c: In function ‘ft_treeclear’: code/parse_tree.c:128:9: error: infinite recursion detected [-Werror=infinite-recursion] 128 | void ft_treeclear(t_tree **tree, void (*del)(void*)) | ^~~~~~~~~~~~ code/parse_tree.c:130:9: note: recursive call 130 | ft_treeclear(&((*tree)->left), del); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make: *** [Makefile:34: obj/parse_tree.o] Error 1
我的疑问是:tree->left和tree->right并非与tree相同的指针,编译器为何能判定存在无限递归?
问题解答
编译器触发无限递归警告,核心原因是你的函数没有终止递归的条件。
当前代码里,不管传入的*tree是不是NULL,都会直接递归调用ft_treeclear处理左右子树——如果*tree是NULL,访问(*tree)->left会直接触发未定义行为,而编译器能分析出:只要函数被调用,就一定会执行递归调用,没有任何分支能让递归停止,所以判定为无限递归。
正确的写法应该先判断*tree是否为NULL,如果是直接返回,终止递归:
void ft_treeclear(t_tree **tree, void (*del)(void*)) { if (*tree == NULL) return; ft_treeclear(&((*tree)->left), del); ft_treeclear(&((*tree)->right), del); del((*tree)->content); free(*tree); *tree = NULL; }
这样编译器就能看到明确的递归终止条件,不会再报无限递归错误,同时也避免了空指针解引用的未定义行为。
内容的提问来源于stack exchange,提问作者Bastian
相关产品推荐
相关产品推荐

