1

In the last reading of the file, when it still has to return a line, and the line variable has the content of that line, an invalid pointer error occurs when doing free in the main but that line has content. On the other hand, if the free is placed outside the loop, it reads well, but I need it to be inside to avoid leaks.

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

    fd = open("file.txt", O_RDONLY);
    while ((line = get_next_line(fd)) != NULL)
    {
        printf("%s", line);
        free(line);
    }
    printf("%s", line);
    free(line);
    return(0);
}
#include "get_next_line.h"

char    *cut_line(char  *line, char *new_line)
{
    int i;

    i = 0;
    while (line[i] != '\n' && line[i] != '\0')
        i++;
    if (line[i] == '\n')
        i++;
    while (line[i])
    {
        *new_line = line[i];
        line[i] = '\0';
        new_line++;
        i++;
    }
    while (*new_line)
    {
        *new_line = '\0';
        new_line++;
    }
    return (line);
}

char    *finalize_line(char **line, char **new_line)
{
    *line = cut_line(*line, *new_line);
    if (**new_line == '\0')
    {
        free(*new_line);
        *new_line = NULL;
    }
    if (**line == '\0' && !*new_line)
    {
        free(*line);
        *line = NULL;
        return (NULL);
    }
    return (*line);
}

char    *get_next_line(int fd)
{
    static char *new_line;
    char        *buffer;
    char        *line;
    int         read_bytes;

    buffer = ft_calloc(BUFFER_SIZE + 1, sizeof(char));
    if (!new_line)
        new_line = ft_calloc(BUFFER_SIZE + 1, sizeof(char));
    if (fd < 0 || BUFFER_SIZE <= 0 || !buffer || !new_line)
        return (free_null(&buffer, &new_line));
    line = ft_strjoin(new_line, buffer, 0);
    read_bytes = 1;
    while (!(ft_strchr(buffer, '\n')) && read_bytes > 0)
    {
        read_bytes = read(fd, buffer, BUFFER_SIZE);
        if (read_bytes == 0)
            break ;
        if (read_bytes == -1)
            return (free_null(&buffer, &new_line));
        buffer[read_bytes] = '\0';
        line = ft_strjoin(line, buffer, 1);
    }
    free(buffer);
    return (finalize_line(&line, &new_line));
}
char    *ft_strjoin(char *s1, char *s2, int flag)
{
    char    *aux_s1;
    int     i;
    int     j;

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

I have tried changing the function instead of traversing the pointer to traverse with an iterator but it also gives me an error. Also this happens with a buffer size of 10 or 100, if I use a buffer size of 1 or 10000 it works. I don't know if it's a problem with how I have the main structured or if it's something in the program itself.

2
  • 1
    The while loop ends when get_next_line() returns null, and then you try to print and free that null pointer...
    – Shawn
    Commented May 28 at 13:46
  • 1
    You need to understand how loop conditions work. Inside the loop the condition is true, so line is not null. There is no need to check it again, you know it is not null. It's too late to check it after use anyway, and freeing a null pointer is perfectly OK, so the check is triple useless. After the loop the condition is false, so (line is null, so any attempt to print it is an error. Commented May 28 at 15:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.