C语言中stdin相关内存泄漏问题排查求助
内存泄漏排查与stdin疑问的解决方案
嘿,我来帮你拆解这个问题!首先得澄清一个误区:你看到valgrind里文件描述符0/1/2未关闭不属于内存泄漏,这些是从父进程继承的终端句柄,程序正常退出后操作系统会自动回收,完全不用手动调用close(0),这根本不是问题的根源。
真正的内存泄漏来自你的parse函数,咱们一步步看:
1. 泄漏的核心原因
先看你的parse核心代码:
char result[250] = "some text string here"; char *target = malloc(sizeof(char) * 250); target = strdup(result); return target;
这里犯了一个非常典型的指针覆盖错误:
- 你先用
malloc分配了250字节的内存,把这块内存的地址存在target指针里 - 紧接着调用
strdup(result)——这个函数会自动分配新的内存来复制字符串,然后把新内存的地址直接赋值给target - 这下好了,原来
malloc得到的内存地址被彻底覆盖了,你再也找不到它的指针,导致这250字节的内存永远没法被free。每次调用parse就会泄漏250字节,两次调用正好对应valgrind里的「500字节2块」泄漏记录。
2. 两种修复方案
选其中一种就行:
方案一:删掉多余的malloc(推荐)
既然strdup会自动帮你分配内存,那之前的malloc完全是画蛇添足,直接删掉:
char result[250] = "some text string here"; char *target = strdup(result); return target;
方案二:用strcpy代替strdup(手动管理内存)
如果你想自己控制内存分配,就用strcpy把字符串复制到已分配的内存里,别用strdup覆盖指针,记得还要加内存分配失败的判断:
char result[250] = "some text string here"; char *target = malloc(sizeof(char) * 250); if (target == NULL) { // 一定要加,避免空指针错误 // 这里可以处理内存分配失败的情况,比如返回NULL或者退出程序 return NULL; } strcpy(target, result); return target;
3. 关于stdin的额外提醒
你怀疑内存泄漏和stdin有关,但从valgrind的输出看,stdin的文件描述符0是正常的终端句柄,完全不用担心。不过你的主循环里while(!feof(stdin))有个小陷阱:feof要在IO操作之后判断才准确,不然可能会让循环多执行一次。可以改成更严谨的写法:
char line[MAX_BUFFER] = {}; char *commands; fputs("? ", stdout); while(fgets(line, MAX_BUFFER, stdin)) { Command cmd = {}; commands = parse(&cmd, line); printf("%s",commands); free(commands); fputs("? ", stdout); }
这样就避免了feof的判断问题,逻辑更顺畅。
内容的提问来源于stack exchange,提问作者Unik Rider Sam
相关产品推荐
相关产品推荐

