无法释放C中的内存

时间:2016-11-26 14:25:27

标签: 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);
}

get_line function

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)

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:-1)

你必须使用free()释放在malloc()之前分配的内存; 您可以查看此答案https://stackoverflow.com/a/9069486/7007823。希望它有所帮助:)