如何排查C语言get_next_line函数的内存泄漏问题?
get_next_line 内存泄漏问题修复方案
你的get_next_line功能正常但存在内存泄漏,主要是以下几个点遗漏了内存释放,还有部分逻辑错误导致的问题:
1. join_buffers调用时未释放旧的动态内存
在read_file的循环中,第一次传入的buffer是静态栈数组(无需释放),但后续每次调用join_buffers后,buffer会指向新的动态分配内存,旧的动态内存被直接覆盖,没有释放,这是主要泄漏源。
修复:
修改read_file,统一使用动态内存管理,每次生成新的拼接内存后释放旧的:
char *read_file(char *buffer, int fd) { int bytes_read; char buff_read[BUFFER_SIZE + 1]; char *dynamic_buf; // 先将静态buffer内容复制到动态内存,统一后续管理 dynamic_buf = malloc(strlen(buffer) + 1); if (!dynamic_buf) return NULL; strcpy(dynamic_buf, buffer); // 清空静态buffer,避免后续混淆 memset(buffer, 0, BUFFER_SIZE + 1); bytes_read = -1; while (!search_char(dynamic_buf, '\n')) { bytes_read = read(fd, buff_read, BUFFER_SIZE); if (bytes_read == -1) { free(dynamic_buf); // 出错时释放已分配内存 return NULL; } if (bytes_read == 0) break; buff_read[bytes_read] = '\0'; char *temp = dynamic_buf; dynamic_buf = join_buffers(dynamic_buf, buff_read); free(temp); // 释放旧的动态内存 if (!dynamic_buf) return NULL; } return dynamic_buf; }
2. read_file出错返回时未清理已分配内存
当read调用返回-1时,原代码直接返回NULL,但此时已经分配的动态内存没有被释放,造成泄漏。上面的修复已经包含了这个场景的内存释放。
3. modify中malloc失败时未释放line
如果return_line的malloc调用失败,原代码直接返回NULL,但line的动态内存没有被释放,导致泄漏。
修复:
char *modify(char buffer[], char *line) { const int size = ft_strclen(line, '\n') + 1; const int total = strlen(line) - size; int i; char *return_line; i = 0; return_line = malloc(sizeof(char) * (ft_strclen(line, '\n') + 2)); if (!return_line) { free(line); // 失败时释放line return NULL; } while (i < size && line[i]) { return_line[i] = line[i]; i++; } return_line[i] = '\0'; i = 0; while (i < total && line[size + i]) { buffer[i] = line[size + i]; i++; } buffer[i] = '\0'; free(line); return return_line; }
4. get_next_line中空内容判断未释放line
当line[0] == '\0' && buffer[0] == '\0'时,原代码直接返回NULL,但line是动态分配的内存,没有被释放。
修复:
char *get_next_line(int fd) { static char buffer[BUFFER_SIZE + 1]; char *line; if (fd < 0 || BUFFER_SIZE <= 0 || read(fd, 0, 0) < 0) return NULL; buffer[BUFFER_SIZE] = '\0'; line = read_file(buffer, fd); if (!line) return NULL; if (line[0] == '\0' && buffer[0] == '\0') { free(line); // 释放空内容的line return NULL; } line = modify(buffer, line); return line; }
额外逻辑错误:join_buffers的字符串拼接逻辑错误
原join_buffers中提前设置new[length] = '\0'会导致后续复制的buf2内容被截断,而且循环条件有问题,修复后的join_buffers:
char *join_buffers(char *buf1, char *buf2) { const int len1 = strlen(buf1); const int len2 = strlen(buf2); const int total_len = len1 + len2; char *new; int i = 0; new = malloc(sizeof(char) * (total_len + 1)); if (!new) return NULL; // 复制buf1 while (i < len1) { new[i] = buf1[i]; i++; } // 复制buf2 int k = 0; while (k < len2) { new[i++] = buf2[k++]; } new[i] = '\0'; return new; }
其他注意点
- 原代码中
BUFFERSIZE = 10应该是#define BUFFER_SIZE 10,否则会编译错误,建议修正宏定义。 - 确保
ft_strclen和search_char函数逻辑正确,避免因字符串处理错误间接导致的内存问题。
内容的提问来源于stack exchange,提问作者Verdant
相关产品推荐
相关产品推荐

