I have a value being returned from a function which is a pointer to a malloc'd address which stores a string value. That string value is what I want to return. But to prevent leaks I need to free that same address, which in turn makes me lose the value I want to return.
I tried creating a tmp
pointer as work around but I assume I'm doing something very wrong.
Here's a little code snippet, where line
is what needs to be free'd, but also its value needs to be returned.
char *get_next_line(int fd)
{
static char *storage;
char *buffer;
char *line;
char *tmp;
tmp = NULL;
line = NULL;
if (!fd || BUFFER_SIZE <= 0)
return (NULL);
read_to_buffer(fd, &buffer, &storage);
free(buffer);
tmp = line;
line = extract_line(storage); // extract_line() returns a malloc'd pointer.
free(&tmp);
return (line);
}
CodePudding user response:
It is always a good (better) idea to provide a buffer, instead of allocating a buffer and returning it. If you write a function and that function returns an allocated buffer, you can't be sure, that the buffer will be freed.
Therefore, the function should accept a buffer (and its size) and use that buffer instead. The specification could allow to pass a NULL
pointer to let the function allocate a buffer (which has to be freed by the user via a specified function, e.g. free
).
e.g.
//instead
char* get_next_line(int fd);
//do
char* get_next_line(int fd, char *dst, int dst_len);
The second version also has the advantage to reuse a single buffer, instead of an allocation at each and every call.
"A clever person solves a problem. A wise person avoids it."
Albert Einstein
CodePudding user response:
tmp = line;
line = extract_line(storage); // extract_line() returns a malloc'd pointer.
free(&tmp);
return (line);
In the above code, both tmp
and line
are pointing to the same memory. So when tmp
is freed, essentially the memory pointed to by line
is also freed. And any attempt to use tmp
after line
has been freed will lead to undefined behaviour.
From C11, Memory Management Functions:
free()
:
....Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
Re:
But to prevent leaks I need to free that same address, which in turn makes me lose the value I want to return.
C does not allow you to use memory after it has been freed. There's no need to free()
the memory in this function if you have to return it. It will only ever result in a memory leak if you forgot to free()
the memory (in the calling function) once you're done with it.
where line is what needs to be free'd, but also its value needs to be returned.
If the memory pointed to by line
is required for further processing, then there's no need for it to be freed in the function get_next_line
.
Aside: free(&tmp);
should be free (tmp);
. And the parentheses after the return
statements are redundant.