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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:25:25