c - C 中无法释放内存

标签 c valgrind

我无法释放我的 C 程序中的内存,当我运行该程序时,我得到 12 次分配和 3 次释放或 24 次分配和 8 次释放。我正在释放正在使用的两个变量,但仍然出现泄漏。我在这里做错了什么? 注意我不允许使用 libc 的函数,我必须重新编码它们,这是一项学校作业。

我的 memalloc.c 函数

void    *ft_memalloc(size_t size)
{
    void    *temp;

    //needs to be freed from the caller
    temp = (void *)malloc(sizeof(*temp) * (size + 1));
    if (temp)
        ft_bzero(temp, size + 1);
    return (temp);
}

我的strsub.c

char    *ft_strsub(char const *s, unsigned int start, size_t len)
{
    char    *sub;

    //sub needs to be freed from the caller
    sub = ft_memalloc(len + 1);
    if (sub)
        ft_memcpy(sub, s + start, len);
    return (sub);
}

我的strsplit.c

static int  count_words(char *s, char c)
{
    int words;

    words = 0;
    while (*s && *s == c)
        ++s;
    if (*s)
        words = 1;
    while (*s)
    {
        if (*s == c && s[1] && s[1] != c)
            ++words;
        ++s;
    }
    return (words);
}

char        **ft_strsplit(char const *s, char c)
{
    int     words;
    char    *start;
    char    **result;

    words = count_words((char *)s, c);
    if (!s || !c)
        return (NULL);
    result = (char **)malloc(sizeof(char *) * (count_words((char *)s, c) + 1));
    start = (char *)s;
    while (*s)
    {
        if (*s == c)
        {
            if (start != s)
                *(result++) = ft_strsub(start, 0, s - start);
            start = (char *)s + 1;
        }
        ++s;
    }
    if (start != s)
        *(result++) = ft_strsub(start, 0, s - start);
    *result = NULL;
     return (result - words);
}

获取行函数

int ft_get_line_helper(char *text, int buf_size, char **line, const int fd)
{
    int     position;
    int     c;

    position = 0;
    while (1)
    {
        c = ft_getchar(fd);
        if (c == 0 || c == '\n')
        {
            text[position] = '\0';
            *line = text;
            return (1);
        }
        else
            text[position] = c;
        position++;
        if (position >= buf_size)
        {
            buf_size += BUFF_SIZE;
            text = ft_realloc(text, buf_size);
            if (!text)
                return (-1);
        }
    }
    return (1);
}

int get_next_line(const int fd, char **line)
{
    char    *text;
    int     buf_size;

    buf_size = BUFF_SIZE;
    text = (char *)malloc(sizeof(char) * buf_size);
    if (fd < 0 || !text || !line)
        return (-1);
    return (ft_get_line_helper(text, buf_size, line, fd));
}

main.c

void    prompt(char **commands)
{
    ft_putstr(GRN);
    ft_putstr("$> ");
    ft_putstr(RESET);
    get_next_line(0, commands);
}

int main(int ac, char const **av, char **envp)
{
    char    *get_line;
    char    **user_comm;

     //voided for now will use them later
     (void)ac;
     (void)av;
     (void)envp;
    while (42) {
        prompt(&get_line);
        {
             user_comm = ft_strsplit(get_line, ' ');
             if (ft_strequ(user_comm[0], "exit"))
                exit(0);
             ft_putstr(user_comm[0]);
             //freeing my variables here
             free(user_comm);
             free(get_line);
        }
     }
     return 0;
}

valgrind 结果

==7342== 
==7342== HEAP SUMMARY:
==7342==     in use at exit: 80 bytes in 8 blocks
==7342==   total heap usage: 18 allocs, 10 frees, 320 bytes allocated
==7342== 
==7342== 26 bytes in 5 blocks are definitely lost in loss record 3 of 4
==7342==    at 0x4C2DB9D: malloc (vg_replace_malloc.c:299)
==7342==    by 0x400CA1: ft_memalloc (in /home/julekgwa/minishell/minishell)
==7342==    by 0x400B7E: ft_strsub (in /home/julekgwa/minishell/minishell)
==7342==    by 0x400900: ft_strsplit (in /home/julekgwa/minishell/minishell)
==7342==    by 0x4006E3: main (main.c:23)
==7342== 
==7342== LEAK SUMMARY:
==7342==    definitely lost: 26 bytes in 5 blocks
==7342==    indirectly lost: 0 bytes in 0 blocks
==7342==      possibly lost: 0 bytes in 0 blocks
==7342==    still reachable: 54 bytes in 3 blocks
==7342==         suppressed: 0 bytes in 0 blocks
==7342== Reachable blocks (those to which a pointer was found) are not shown.
==7342== To see them, rerun with: --leak-check=full --show-leak- kinds=all
==7342== 
==7342== For counts of detected and suppressed errors, rerun with: -v
==7342== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

最佳答案

我已经解决了这个问题,创建了一个用于释放 strsplit 返回值的函数。

void freesplit( char **split )
{
    free( split[ 0 ] );
    free( split );
}

int main(int ac, char const **av, char **envp)
{
    char    *get_line;
    char    **user_comm;

    (void)ac;
    (void)av;
    (void)envp;
    while (42) {
        prompt(&get_line);
        user_comm = ft_strsplit(get_line, ' ');
        if (ft_strequ(user_comm[0], "exit")) {
            freesplit(user_comm);
            free(get_line);
            exit(0);
        }
        ft_run_commands(user_comm, get_line, envp);
        freesplit(user_comm);
        free(get_line);
    }
    return 0;
}

==7407== 
==7407== HEAP SUMMARY:
==7407==     in use at exit: 0 bytes in 0 blocks
==7407==   total heap usage: 30 allocs, 30 frees, 527 bytes allocated
==7407== 
==7407== All heap blocks were freed -- no leaks are possible
==7407== 
==7407== For counts of detected and suppressed errors, rerun with: -v
==7407== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

关于c - C 中无法释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40819340/

相关文章:

c - 使用 * 制作循环

macos - Macports 安装错误

opencv - convertTo 函数中 Mat 的内存泄漏

c++ - 段错误/使用大小为 8 的未初始化值

c++ - 奇怪的段错误和valgrind分析

c++ - Eclipse、CDT、(N)Curses 和调试/分析

c++ - 在运算符之间添加间距的目的是什么?

c - mod C 的问题

c - 按引用传递数组

c - 为什么带有 listen(sockfd, 2) 调用的服务器能够接受 3 个连接?