Search code examples
cmallocfree

variable char* wont free up?


so i'm coding a function that takes a line from a file and print it, the problem is i can't free up the char* variable here's the code

int main()
{
    char *line; 
    int fd;

    fd = open("text.txt", O_RDONLY);
    int ret = 0;
        while (ret < 3)
        {
            get_next_line(fd, &line);
            printf("%s\n", line);
            free(line);
            ret++;
        }

}

the line variable it get allocated in the get_next_line function with the function

strdup("");

here is the get_next_line func

int get_next_line(int fd, char **line)
{
    char *buff;
    int bwr;
    char *ptr;
    int bol;
    static char *rem;


    bol = 1; 
    buff = (char *)malloc(sizeof(char) * (BUFFER_SIZE + 1));
    if(rem)
    {
        *line = ft_strdup(rem);
        printf("---1ST---%s\n", rem);
        free(rem);
        printf("---2ND---%s\n", rem);
    }
    else
        *line = ft_strdup("");
    while (bol && (bwr = read(fd, buff, BUFFER_SIZE)))
    {
        buff[bwr] = '\0';
        if ((ptr = ft_strchr(buff, '\n')))
        {
            rem = ft_strdup(ptr + 1);
            *ptr = '\0'; 
            bol = 0;
        }
        *line = ft_strjoin(*line ,buff);
    }
        return(0);
}

so i don't know why it won't free up the line

PS: i'm using lldb to check the memory blocks, Thanks.


Solution

  • I'm only gonna address the leaks in your program: The first one is in this line:

    *line = ft_strjoin(*line ,buff);
    

    What happens is that since the return value of your ft_strjoin is *line, the old memory address that *line used to point to is lost without being freed and now *line points to another memory address (the one that holds *line + buff).

    You have two ways to correct this problem:

    The first one is to do something like this:

    char *to_free = *line;
    *line = ft_strjoin(*line, buff);
    free(to_free);
    

    This will make to_free point the same memory address that *line points to before being changed by the call to ft_strjoin. The other way (the better one in my opinion), is to implement ft_strjoin that takes a 3d argument int n for example, if n = 1 you free the first argument of ft_strjoin, if n = 2 you free the 2nd argument, if n = 3 you free both (Be careful on where you free them inside your function).

    if (rem)
    

    could return true even if you free it because you didn't do a rem = NULL explicitly afterwards (You're also calling printf to print rem after your free rem.

    The last problem is that you're not freeing buff anywhere. You should free it before exiting your get_next_line.