valgrind was complaining about definite mem leaks in `join`
so I refactored the offending code a little and removed the
inconseqential leak (which may mask real leaks in future).

cheers,
Pádraig.
>From c068a9ab6a164c0e713bb61706c6f40b8e18bb92 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Wed, 27 Jan 2010 02:17:36 +0000
Subject: [PATCH] maint: fix an inconsequential mem leak in join

* src/join.c (join): Refactor the code that checks for misorder
at the tail of the files.  The most significant change here is
that freeline() is called thus silencing a valgrind warning about
a definite but inconseqential memory leak.
(freeline): Make more general by doing nothing when passed NULL,
and setting freed pointers to NULL.
---
 src/join.c |   37 ++++++++++++++++++-------------------
 1 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/src/join.c b/src/join.c
index 4792f16..d86e62c 100644
--- a/src/join.c
+++ b/src/join.c
@@ -272,7 +272,10 @@ xfields (struct line *line)
 static void
 freeline (struct line *line)
 {
+  if (line == NULL)
+    return;
   free (line->fields);
+  line->fields = NULL;
   free (line->buf.buffer);
   line->buf.buffer = NULL;
 }
@@ -486,12 +489,10 @@ delseq (struct seq *seq)
 {
   size_t i;
   for (i = 0; i < seq->alloc; i++)
-    if (seq->lines[i])
-      {
-        if (seq->lines[i]->buf.buffer)
-          freeline (seq->lines[i]);
-        free (seq->lines[i]);
-      }
+    {
+      freeline (seq->lines[i]);
+      free (seq->lines[i]);
+    }
   free (seq->lines);
 }
 
@@ -604,11 +605,8 @@ static void
 join (FILE *fp1, FILE *fp2)
 {
   struct seq seq1, seq2;
-  struct line **linep = xmalloc (sizeof *linep);
   int diff;
-  bool eof1, eof2, checktail;
-
-  *linep = NULL;
+  bool eof1, eof2;
 
   /* Read the first line of each file.  */
   initseq (&seq1);
@@ -691,25 +689,26 @@ join (FILE *fp1, FILE *fp2)
         seq2.count = 0;
     }
 
-  /* If the user did not specify --check-order, and the we read the
+  /* If the user did not specify --check-order, then we read the
      tail ends of both inputs to verify that they are in order.  We
      skip the rest of the tail once we have issued a warning for that
      file, unless we actually need to print the unpairable lines.  */
+  struct line *line = NULL;
+  bool checktail = false;
+
   if (check_input_order != CHECK_ORDER_DISABLED
       && !(issued_disorder_warning[0] && issued_disorder_warning[1]))
     checktail = true;
-  else
-    checktail = false;
 
   if ((print_unpairables_1 || checktail) && seq1.count)
     {
       if (print_unpairables_1)
         prjoin (seq1.lines[0], &uni_blank);
       seen_unpairable = true;
-      while (get_line (fp1, linep, 1))
+      while (get_line (fp1, &line, 1))
         {
           if (print_unpairables_1)
-            prjoin (*linep, &uni_blank);
+            prjoin (line, &uni_blank);
           if (issued_disorder_warning[0] && !print_unpairables_1)
             break;
         }
@@ -720,18 +719,18 @@ join (FILE *fp1, FILE *fp2)
       if (print_unpairables_2)
         prjoin (&uni_blank, seq2.lines[0]);
       seen_unpairable = true;
-      while (get_line (fp2, linep, 2))
+      while (get_line (fp2, &line, 2))
         {
           if (print_unpairables_2)
-            prjoin (&uni_blank, *linep);
+            prjoin (&uni_blank, line);
           if (issued_disorder_warning[1] && !print_unpairables_2)
             break;
         }
     }
 
-  free (*linep);
+  freeline (line);
+  free (line);
 
-  free (linep);
   delseq (&seq1);
   delseq (&seq2);
 }
-- 
1.6.2.5

Reply via email to