POSIX getline allocates or grows the buffer through the pointer you pass, and the buffer belongs to the caller from the first call onwards. That includes the call that returns -1. The specification leaves the freeing to the application, and the Linux man page states it directly, the buffer should be freed even if getline failed.
So the loop has a single release, after it ends, whatever the reason it ended.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *line = NULL;
size_t cap = 0;
ssize_t n;
long lines = 0;
while ((n = getline(&line, &cap, stdin)) != -1)
lines++;
if (ferror(stdin))
perror("getline");
free(line);
printf("%ld\n", lines);
return 0;
}
Two points follow. First, -1 covers both end of file and a read error, so ferror or feof is the only way to tell them apart, and neither case changes who frees line. Second, line and cap must start as a null pointer and zero, or as a buffer obtained from malloc with its real size. A stack array is not acceptable, because getline may pass it to realloc.
The mistake I see most is a free(line) inside an error branch and none on the end-of-file path.
