C语言实现Linux tree -pugs命令存在内存泄漏与free时段错误问题
问题分析与解决建议
内存泄漏常见原因(结合你的代码场景)
你贴出的代码里缺失了tree_walk_counter实现、pre_name/user_name/Permissions等变量的赋值逻辑,结合常见的tree命令实现逻辑,泄漏大概率来自以下几个场景:
pre_name变量:如果你每次遍历文件/目录时用strdup/malloc为其分配内存存储路径/文件名,没有在每次赋新值前释放旧内存,也没有在程序退出前释放最后一次分配的内存,就会产生批量泄漏。user_name/group_name变量:如果你调用getpwuid/getgrgid获取用户名/组名后,用strdup把返回的静态字符串拷贝到了这两个指针里,没有主动释放也会产生泄漏。注意不要直接释放getpwuid返回的结构体内部的字符串指针,那是静态分配的,释放会导致段错误。- 其他未贴出的动态分配内存:比如权限字符串
Permissions、路径缓存等如果是动态分配的,没有主动释放也会产生泄漏。
free触发段错误的常见原因
你尝试释放内存时崩溃,通常是以下几种情况:
- 释放的不是堆内存指针:比如把
pre_name指向了栈上的字符数组、或者字符串常量,对这类指针调用free必然崩溃。 - 重复释放:同一个指针被free多次,尤其是free后没有把指针置为NULL,后续误操作再次free。
- 堆内存结构被破坏:比如给字符串分配内存时少分配了1字节存结束符
\0,拷贝字符串时越界改写了malloc的元数据,free时就会触发段错误。
具体解决步骤
- 先精准定位泄漏点:运行valgrind时加上参数
--leak-check=full --show-leak-kinds=all,valgrind会直接输出未释放内存是在哪一行代码分配的,不用盲猜。 - 针对性释放内存:
- 对于
pre_name这类每次遍历都要更新的动态指针,每次赋新值前先释放旧内存,初始化和free后都把指针置为NULL:
// 初始化时 char *pre_name = NULL; // 每次要更新pre_name前 if (pre_name != NULL) { free(pre_name); pre_name = NULL; } pre_name = strdup(name); // 假设你用strdup分配内存 // 程序退出前再释放最后一次分配的pre_name if (pre_name != NULL) free(pre_name);- 对于
user_name/group_name:如果是你自己strdup出来的,程序退出前释放即可;如果是直接指向getpwuid返回的静态字符串,不需要释放。
- 对于
- 排查越界问题:所有字符串拷贝操作前确认目标内存长度足够,预留结束符的位置。
内容的提问来源于stack exchange,提问作者Maoz Lev
相关产品推荐
相关产品推荐

