C语言static变量引发内存泄漏问题求助
解决get_next_line的1字节内存泄漏问题
泄漏原因分析
你的内存泄漏来自两个核心问题,同时伴随一处逻辑错误:
1. ft_strjoin调用未释放旧缓冲区
在get_next_line中,你直接执行str = ft_strjoin(str, buf);,但ft_strjoin每次都会分配新内存,原str指向的旧内存从未被释放——这会导致累积性内存泄漏,只是测试文件较小时未被大量触发。
2. 换行结尾行残留的1字节空字符串未释放
当文件最后一行以\n结尾时,offset函数会分配1字节内存存储空字符串并赋值给static变量str。如果后续未再次调用get_next_line触发offset的释放逻辑,这块内存会一直占用到程序结束,被ASAN检测为泄漏。
3. main函数循环逻辑错误
初始line未初始化就执行while (line != NULL)判断,属于未定义行为,还可能导致少调用一次get_next_line,无法触发残留内存的释放。
修复方案
方案1:修复ft_strjoin的内存泄漏
在get_next_line中,调用ft_strjoin前先释放旧的str:
// 替换原有的str = ft_strjoin(str, buf); char *tmp = ft_strjoin(str, buf); free(str); str = tmp;
方案2:消除1字节空字符串的分配
修改offset函数,当剩余内容为空时直接返回NULL,避免分配1字节内存:
char *offset(char *a) { char *buf; int i; int x; i = 0; x = 0; while (a[i] && a[i] != '\n') i++; if (a[i] == '\0') { free(a); return (NULL); } i++; // 计算剩余长度,为空则直接释放返回 int remaining_len = ft_strlen(a) - i; if (remaining_len == 0) { free(a); return (NULL); } buf = (char *)malloc(remaining_len + 1); if (!buf) { free(a); return (NULL); } while (a[i + x]) { buf[x] = a[i + x]; x++; } buf[x] = '\0'; free(a); return (buf); }
方案3:修复main函数的循环逻辑
采用先获取行、再判断的正确循环结构,避免未初始化指针问题:
int main(int argc, char *argv[]) { char *line; int fd; if (argc < 2) { printf("Usage: %s <file>\n", argv[0]); return (1); } fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("Failed to open file"); return (1); } // 正确循环逻辑:先获取行,再判断是否有效 line = get_next_line(fd); while (line != NULL) { printf("%s", line); free(line); line = get_next_line(fd); } close(fd); return (0); }
方案4:主动清理static缓冲区
在get_next_line返回NULL时,确保static变量str被彻底释放:
char *get_next_line(int fd) { static char *str; char *buf; int i; if (fd < 0 || BUFFER_SIZE <= 0) return (NULL); buf = (char *)malloc((sizeof(char) * BUFFER_SIZE) + 1); if (!buf) return (NULL); i = 1; while (!(ft_strchr(str, '\n')) && i != 0) { i = read(fd, buf, BUFFER_SIZE); if (i == -1) { free(buf); return (NULL); } buf[i] = '\0'; char *tmp = ft_strjoin(str, buf); free(str); str = tmp; } free(buf); buf = next_line(str); str = offset(str); // 无更多行时,确保str已释放 if (!buf && str) { free(str); str = NULL; } return (buf); }
内容的提问来源于stack exchange,提问作者pantsoo
相关产品推荐
相关产品推荐

