The tester I am using shows that there are leaks all over the place, for instance with the memory allocated by ft_strdup.
When i go up the chain of functions I am under the impression that in any scenario ft_strdup is called, the result will be returned by each function until the end of get_next_line without any opportunity to free it.
char *get_next_line(int fd)
{
static char *leftover;
char *next_line;
if (BUFFER_SIZE <= 0 || !fd)
return (NULL);
if (!leftover)
leftover = ft_read_from_file(fd, leftover);
if (!leftover)
return (NULL);
next_line = ft_find_line(leftover);
leftover = ft_strchr(leftover, '\n');
if (leftover)
leftover++;
return (next_line);
}
char *ft_read_from_file(int fd, char *leftover)
{
char *buffer;
long long bytes_read;
buffer = malloc(sizeof(char) * (BUFFER_SIZE + 1));
if (!buffer)
return (NULL);
bytes_read = read(fd, buffer, BUFFER_SIZE);
if (bytes_read < 1)
{
free(buffer);
return (NULL);
}
else
buffer[bytes_read] = '\0';
leftover = ft_strjoin(leftover, buffer);
free(buffer);
return (leftover);
}
char *ft_find_line(char *leftover)
{
char *str;
int i;
int j;
j = 0;
i = 0;
while (leftover[i] != '\n' && leftover[i])
i++;
str = malloc(sizeof(char) * (i + 2));
while (i > j)
{
str[j] = leftover[j];
j++;
}
if (leftover[j] == '\n')
{
str[j] = leftover[j];
j++;
}
str[j] = '\0';
return (str);
}
char *ft_strchr(const char *s, int c)
{
int i;
i = 0;
while (s[i] && s[i] != (char)c && i < BUFFER_SIZE)
i++;
if (s[i] == (char)c)
return ((char *)&s[i]);
return ((void *)0);
}
char *ft_strjoin(char const *s1, char const *s2)
{
int i;
int j;
char *str;
i = 0;
j = 0;
if (!s1 && !s2)
return (NULL);
if (!s1)
return (ft_strdup(s2));
str = malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char));
if (str == NULL)
return (NULL);
while (s1[i])
{
str[j++] = s1[i++];
}
i = 0;
while (s2[i])
{
str[j++] = s2[i++];
}
str[j] = '\0';
return (str);
}
char *ft_strdup(const char *s1)
{
int i;
int size;
char *ptr;
i = 0;
size = ft_strlen(s1);
ptr = malloc(sizeof(char) * size + 1);
if (ptr == NULL)
return (NULL);
while (s1[i])
{
ptr[i] = s1[i];
i++;
}
ptr[i] = '\0';
return (ptr);
}
int ft_strlen(const char *str)
{
int i;
i = 0;
while (str[i])
i++;
return (i);
}
You malloc()
a string in ft_read_from_file()
and you use strchr()
with the malloc ptr.
Here a minimal example :
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
char * ptr;
ptr = malloc(sizeof(char) * 5);
strcpy(ptr, "test");
printf("%p\n", ptr);
ptr = strchr(ptr, 's');
printf("%p\n", ptr);
free(ptr); // free(): invalid pointer
return (0);
}
Also why if (BUFFER_SIZE <= 0 || !fd)
?
0
is a valid file descriptor and you probably need to handle it.
Also is not really a good way to check the BUFFER_SIZE
.
Here another way :
# if BUFFER_SIZE <= 0
# error "BUFFER_SIZE can't be <= 0"
# endif