需要帮助清理内存泄漏并使用 malloc 和 free 解决 C 代码中的分段错误

Need help cleaning memory leaks and resolving segmentation fault in C code using malloc and free

提问人:deboracaracol 提问时间:6/1/2023 更新时间:6/2/2023 访问量:72

问:

我一直在用 C 语言编写此代码,它有很多我不知道如何清理的泄漏。

当我在 main 上调用 get_next_line 时,我想要的是让它返回 .txt 文件的下一行。

有人可以帮我吗?


size_t  ft_strlen(char *s)
{
    size_t  i;

    if (!s)
        return (0);
    i = 0;
    while (s[i] != '\0')
        i++;
    return (i);
}

char    *ft_strchr(char *s, int c)
{
    size_t  i;

    i = 0;
    if (!s)
        return (0);
    while ((s[i] != '\0') && (s[i] != (unsigned char)c))
        i++;
    if ((s[i] == (unsigned char)c) || (c == '\0'))
        return ((char *)&s[i]);
    return (0);
}

char    *ft_substr(char *s, unsigned int start, size_t len)
{
    size_t  i;
    size_t  j;
    char    *sub;

    i = 0;
    j = 0;
    if (start >= ft_strlen(s) || !s || !len)
    {
        sub = malloc(1 * sizeof(char));
        sub[0] = '\0';
        return (sub);
    }
    while (s[start + j] != '\0' && j < len)
        j++;
    if (s[start + j] != '\0')
        j++;
    sub = malloc((j + 1) * sizeof(char));
    if (!sub)
    {
        free(s);
        return (0); 
    }
    while (s[start] != '\0' && j > i)
        sub[i++] = s[start++];
    sub[i] = '\0';
    //free(s);
    return (sub);
}

char    *ft_strjoin(char *s1, char *s2)
{
    char    *cat;
    size_t  i;
    size_t  j;

    i = 0;
    j = 0;
    if (!s1)
    {
        s1 = malloc(sizeof(char) * 1);
        s1[0] = '\0';
    }
    cat = (char *)malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char));
    if (!cat)
        return (NULL);
    while (s1[i] != '\0')
    {
        cat[i] = s1[i];
        i++;
    }
    while (s2[j] != '\0')
        cat[i++] = s2[j++];
    free(s1);
    cat[i] = '\0';
    return (cat);
}


char    *ft_content(int fd, char *content)
{
    char    *buf;
    int     buf_nb;

    buf_nb = 1;
    buf = (char *)malloc((BUFFER_SIZE + 1) * sizeof(char));
    if (!buf)
        return (0);
    while ((!ft_strchr(content, '\n')) && buf_nb != 0)
    {
        buf_nb = read(fd, buf, BUFFER_SIZE);
        if (buf_nb == -1)
        {
            free(buf);
            free(content);
            return (NULL);
        }
        buf[buf_nb] = '\0';
        content = ft_strjoin(content, buf);
    }
    free(buf);
    return (content);
}

char    *get_next_line(int fd)
{
    static char *content;
    char        *sub;
    int         i;
    int         len;

    i = 0;
    if (fd < 0 || BUFFER_SIZE <= 0)
        return (NULL);
    content = ft_content(fd, content);
    if (content == NULL)
        return (NULL);
    if (content[0] == '\0')
        return (NULL);
    while (content[i] != '\n' && content[i] != '\0')
        i++;
    sub = ft_substr(content, 0, i);
    len = ft_strlen(content);
    i++;
    content = ft_substr(content, i, len);
    return (sub);
}
int    main(void)
{
    int    a = open("exemplo.txt", O_RDONLY);
    printf("%s", get_next_line(a));
    printf("%s", get_next_line(a));
    printf("%s", get_next_line(a));
    printf("%s", get_next_line(a));
    return (0);
}

我已经做了几次更改,但我总是遇到内存泄漏和分段错误。

我所期望的只是阅读文件。

C 分段 - 无故障 Malloc

评论

3赞 dbush 6/1/2023
通过 valgrind 运行代码。如果你对内存管理不善,它会告诉你在哪里。
1赞 Barmar 6/1/2023
欢迎来到 Stack Overflow!不要投射 malloc
0赞 Barmar 6/1/2023
第一次调用时,将是 。所以会尝试在空指针中搜索换行符。这会导致分段错误。ft_contentcontentNULLft_strchr(content, '\n')
1赞 Eugene Sh. 6/1/2023
你有许多不同的小功能。对其中的每一个进行单元测试,以确定问题所在。
1赞 Barmar 6/2/2023
除了 valgrind 之外,这将是学习使用调试器单步执行代码的好时机。

答:

1赞 Tymenko Maxsim 6/2/2023 #1

如果您使用的是编译器 gcc 或 clang,则可以在编译程序时尝试使用命令行选项,以检测任何内存泄漏。-fsanitize=leak

有关更多信息,请参见 gcc 手册中的此页面