C语言opendir/readdir报错free(): invalid size问题求助
排查方案
检查内存分配与越界问题
- 确认
malloc给procName分配的内存大小是否足够容纳整个cmdline内容。如果用固定值(比如1024)分配,当进程的cmdline长度超过这个值时,写入会越界破坏堆元数据,导致free时报错。建议先读取文件大小(或者用动态扩容,比如先分配初始大小,读取后如果不够就realloc),或者在读取时严格限制写入的字节数不超过分配的内存。 - 读取
cmdline后,记得把第一个\0之前的内容作为进程名,手动截断字符串。因为/proc/PID/cmdline里的参数是用\0分隔的,不截断的话后续字符串操作(比如strlen)可能会越界访问。
- 确认
检查
free操作的合法性- 确认没有重复
free同一个指针。比如循环里每次分配procName但没及时释放,最后只free一次;或者在代码逻辑中多次调用free(procName),导致重复释放。 - 确认
free的是malloc/realloc返回的合法指针。如果procName被赋值为字符串字面量(比如procName = "bash")或者栈上数组的地址,这时候调用free就会触发错误。
- 确认没有重复
验证指针初始化与错误处理
- 确保
procName初始化为NULL。如果malloc失败,未初始化的指针是野指针,调用free会触发错误。正确写法是char *procName = NULL;,这样即使malloc失败,free(NULL)是安全的。
- 确保
借助工具定位问题
- 用
gcc -Wall -Wextra -g编译代码,查看所有警告信息,比如隐式类型转换、未初始化变量、指针越界的提示,这些往往是问题的源头。 - 用
valgrind运行程序:valgrind --leak-check=full ./your_program,它会精准指出堆内存的错误类型(比如越界写入、重复释放、野指针)和发生位置。 - 利用core dump调试:用
gdb ./your_program core加载核心转储文件,执行bt查看调用栈,定位到触发free错误的具体代码行,结合上下文分析指针状态。
- 用
排查目录遍历中的内存操作
- 遍历/proc数字目录的循环里,检查是否每次分配
procName后都正确释放。比如循环内分配内存,循环结束后才释放,会导致内存泄漏,但如果循环内错误覆盖了procName的指针(没保存原地址就重新分配),可能导致后续free的是错误的地址。
- 遍历/proc数字目录的循环里,检查是否每次分配
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

