I am reading from stdin. Since I do not know the length of what I will read, I have to use malloc.
I am getting a pointer being freed was not allocated
Sometimes, it happens before free(final), sometimes before free(tmp).
I check that both pointers are correctly are non null after creating them and before making free. Can somebody pin point what I am doing wrong ?
total_size = 0;
final = (char *)malloc(sizeof(char) * 1);
if (!final)
{
printf("Error Allocating Memory for final\n");
return (NULL);
}
while ((ret = read(0, buf, BUF_SIZE)) > 0)
{
tmp = (char *)malloc(sizeof(char) * ft_strlen(final));
if (!tmp)
{
printf("Error Allocating Memory for tmp\n");
return (NULL);
}
strcpy(tmp, final);
if (final)
free(final);
buf[ret] = '\0';
total_size = total_size + ret;
final = (char *)malloc(sizeof(char) * total_size);
if (!final)
{
printf("Error Allocating Memory for final\n");
return (NULL);
}
final = strcat(tmp, buf);
if (tmp)
free(tmp);
}
return (final);
This is a problem for you:
final = (char *)malloc(sizeof(char) * total_size);
[...]
final = strcat(tmp, buf);
You are leaking the allocated memory and aliasing *final
and *tmp
. You can thereafter free one of them, but you must not afterward free the other without first reassigning it to point to a valid dynamically-allocated block.
Overall, it looks like you are going to a lot of unnecessary trouble with tmp
. As far as I can tell, you're just trying to increase the size of the block to which final
points, and that's what realloc()
is for:
size_t desired_size = total_size + ret + 1; // need space for a terminator
char *tmp = realloc(final, desired_size);
if (!tmp) {
perror("Error Allocating More Memory for final");
// realloc() does not free the pointer on failure; at least GLIBC's doesn't
free(final);
return (NULL);
}
final = tmp;
buf[ret] = '\0';
// strcat is wasteful if you already know the destination string's length
strcpy(final + total_size, buf);
total_size += ret;
The reallocated block may or may not start in the same place as the original, but realloc()
takes care of copying the data if necessary.