diff options
author | Ting-Wei Lan <lantw44@gmail.com> | 2017-12-30 22:18:12 +0800 |
---|---|---|
committer | Ting-Wei Lan <lantw44@gmail.com> | 2018-01-02 14:06:09 +0800 |
commit | df8d825b7949225ec9507d912ccdc144dfb5c166 (patch) | |
tree | 7b04a2d528983ec7b44a084d50e7a088bacf07d2 | |
parent | c080ad1bddbd32382e13e5d0b0540281d3b9b86f (diff) | |
download | wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.gz wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.bz2 wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.lz wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.xz wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.zst wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.zip |
freebsd: Fix memory leak in freebsd.ports.find
In function read_entries, we have to keep pointers returned by getline
in an array to be able to free them even if the man page in FreeBSD says
they will be freed when hdestroy is called. It turns out that the man
page is incorrect after reading the source code and POSIX standard.
In function write_maps, we can reset neither line nor len variable
because it will cause getline to malloc a new buffer every time it is
called. If we don't modify the values of these two variables, getline
will use realloc when it needs more space and we only have to free it
after leaving the loop.
I know freebsd.ports.find is a short-lived program and leaking memory
won't cause problems, but I still think we should do memory management
properly to allow using valgrind to check the program.
-rw-r--r-- | freebsd/freebsd.ports.find.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/freebsd/freebsd.ports.find.c b/freebsd/freebsd.ports.find.c index 309ea89..852c2c3 100644 --- a/freebsd/freebsd.ports.find.c +++ b/freebsd/freebsd.ports.find.c @@ -13,6 +13,9 @@ #define msg(...) fprintf(stderr, __VA_ARGS__) #define msgstr(x) fputs((x), stderr) +static char *index_lines[HASH_TABLE_SIZE]; +static size_t index_count = 0; + static void write_maps (const char* list_file) { FILE* fp = fopen (list_file, "r"); if (fp == NULL) { @@ -39,10 +42,10 @@ static void write_maps (const char* list_file) { } printf ("%-32s %s\n", line, hresult->data); - line = NULL; - len = 0; } + free (line); + if (!feof (fp)) { msgstr ("Fail to read the whole list file\n"); perror ("getline"); @@ -101,15 +104,18 @@ static void read_entries (const char* index_file) { .key = pkgname, .data = fullpath }; - if (hsearch (hentry, ENTER) == NULL) { + if (hsearch (hentry, ENTER) == NULL || index_count >= HASH_TABLE_SIZE) { msgstr ("The hash table is full!\n"); exit (5); } + index_lines[index_count++] = line; line = NULL; len = 0; } + free (line); + if (!feof (fp)) { msgstr ("Fail to read the whole index file\n"); perror ("getline"); @@ -135,5 +141,11 @@ int main (int argc, char* argv[]) { read_entries (argv[2]); write_maps (argv[1]); + for (size_t i = 0; i < index_count; i++) { + free (index_lines[i]); + } + + hdestroy (); + return 0; } |