为何使用leaks命令检测不到C程序中未释放的内存泄漏?
我写了一段C程序,用malloc分配内存后没有调用free释放,编译运行后调用leaks命令却显示无内存泄漏,是不是错误使用了leaks?
代码如下:
#include <stdlib.h> #include <stdio.h> int main() { char *str; str = malloc(sizeof(str) * 15); system("leaks a.out"); return 0; }
编译命令:gcc main.c
运行命令:./a.out
leaks输出结果:
leaks Report Version: 4.0
Process 94181: 156 nodes malloced for 8 KB
Process 94181: 0 leaks for 0 total leaked bytes.
明明分配了内存没释放,按道理应该存在内存泄漏才对?
问题原因
leaks的泄漏判定逻辑:leaks判定内存泄漏的核心标准是进程中没有任何存活指针指向该块已分配内存。你的代码里,
str指针还存在于main函数的栈帧中,且明确指向malloc分配的内存块——leaks能检测到这个有效引用,因此不会将其标记为泄漏。调用时机与系统回收机制:你在进程运行过程中调用leaks时,内存块仍被有效引用;而当进程执行到
return 0退出后,操作系统会自动回收该进程占用的所有内存资源,此时再检查也看不到泄漏痕迹。代码的细节问题:
malloc(sizeof(str) *15)是按指针大小分配内存(64位系统下指针大小为8字节),实际分配了120字节。如果你的需求是分配15个char类型的空间,应该写malloc(sizeof(char)*15)或者直接malloc(15)(因为sizeof(char)恒为1)。
正确的测试方法
方法1:让内存块失去引用后再检查
修改代码,让持有内存的指针被销毁或覆盖,使内存块成为无引用状态,这样leaks就能检测到泄漏:
#include <stdlib.h> #include <stdio.h> void allocate_memory() { // 函数返回后,局部指针str被销毁,内存块失去唯一引用 char *str = malloc(15); } int main() { allocate_memory(); system("leaks a.out"); return 0; }
方法2:保持进程运行,外部调用leaks检查
让进程持续运行,在终端通过进程ID单独调用leaks进行检查:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> int main() { char *str = malloc(15); printf("当前进程ID:%d\n", getpid()); getchar(); // 等待输入,让进程保持运行状态 // 不调用free释放内存 return 0; }
编译运行后,在另一个终端执行:
leaks <进程ID>
此时就能看到未被释放的内存块被标记为泄漏。
内容的提问来源于stack exchange,提问作者Mário Lima

