You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何排查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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:40:27