The following block causes a memory leak:
FILE *fp = fopen(path, "r");
char *line = NULL;
size_t len = 0;
ssize_t read = -1;
while ((read = getline(&line, &len, fp)) != -1) {
/*Do something*/
}
120 bytes in 1 blocks are definitely lost...
...getline (getline.c:34)
I can fix this by adding a free()
:
while ((read = getline(&line, &len, fp)) != -1) {
/*Do something*/
}
free(line);
My question is: Why does getline
allocate memory for line
when it fails? And why do I not need to free(line)
for every call to getline
?
getline() , shown above is an interesting use-case because it is a library function that not only allocates memory it leaves to the caller to free, but can fail for a number of reasons, all of which must be taken into account.
The getline method reads a full line from a stream, such as a newline character. To finish the input, use the getline function to generate a stop character. The command will be completed, and this character will be removed from the input.
The getline() function is written in such a way that if the already allocated memory is not enough, getline() will call realloc() to expand the memory block (ISO/IEC TR 24731-2). That's why memory can be allocated only using functions malloc() or realloc().
The setup is such that you can pass a previously allocated block of memory to getline()
, and it will allocate more (realloc()
) if it needs it. (Or you can start with no memory allocated, as here.) It can report failure or EOF, but doesn't release the space that was allocated — hence you need to free it. If the file is an empty file and you start off with no data, you might not get any space allocated; on the other hand, it may have allocated some space before it attempts to get data from the file.
But you know that if the line
pointer is not null, it was allocated and must be freed.
getline can fail in several different ways, and may or may not have realloced the memory one or more times when it fails. To be consistent, it never frees the memory -- see one possible implementation at http://www.opensource.apple.com/source/cvs/cvs-19/cvs/lib/getline.c
Such consistency makes it easier both for the implementation and for the caller ... you just always free the line rather than having to check the error code to see whether to free it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With