On Thu, Feb 26, 2015 at 1:50 PM, Dimitris Papastamos <s...@2f30.org> wrote:
> Sorry, I meant no need to free that strdup().  I will check
> your patch tomorrow.
>

First patch was buggy and I accidentally used a for loop initial
declaration. That's what I get for trying to code too quickly. Here is
a fixed one so you're at least looking at a working patch when you
decide whether or not it's worth the extra code.

-emg
From c2b5985ba92463d3b260a7b46a2ebfd8ee1dd3a9 Mon Sep 17 00:00:00 2001
From: Evan Gates <evan.ga...@gmail.com>
Date: Thu, 26 Feb 2015 14:14:23 -0800
Subject: [PATCH] keep track of allocations due to enstrdup() in match(), then
 free them when we are finished (also spaces->tabs for one indentation
 mistake)

---
 expr.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/expr.c b/expr.c
index ac0e086..be0d8d9 100644
--- a/expr.c
+++ b/expr.c
@@ -1,6 +1,7 @@
 /* See LICENSE file for copyright and license details. */
 #include <inttypes.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "utf.h"
@@ -17,8 +18,24 @@ typedef struct {
        intmax_t n;
 } Val;
 
+/* keep track of memory allocated in match() */
+typedef struct Alloc Alloc;
+struct Alloc {
+       Alloc *next;
+       char *s;
+} *allocs;
+
 static size_t intlen;
 
+static char *
+add_alloc(char *s)
+{
+       Alloc *a = emalloc(sizeof(*a));
+       *a = (Alloc){ allocs, s };
+       allocs = a;
+       return s;
+}
+
 static void
 enan(Val v)
 {
@@ -87,13 +104,10 @@ match(Val vstr, Val vregx)
                d = strtoimax(s, &p, 10);
                if (*s && !*p) /* string matched by subexpression is an integer 
*/
                        return (Val){ NULL, d };
-
-               /* FIXME? string is never free()d, worth fixing?
-                * need to allocate as it could be in buf1 instead of vstr.s */
-               return (Val){ enstrdup(3, s), 0 };
+               return (Val){ add_alloc(enstrdup(3, s)), 0 };
        }
        regfree(&re);
-    str += matches[0].rm_so;
+       str += matches[0].rm_so;
        return (Val){ NULL, utfnlen(str, matches[0].rm_eo - matches[0].rm_so) };
 }
 
@@ -269,6 +283,8 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
+       int ret;
+       Alloc *p;
        intmax_t n = INTMAX_MIN;
 
        /* Get the maximum number of digits (+ sign) */
@@ -280,5 +296,12 @@ main(int argc, char *argv[])
                usage();
        } ARGEND;
 
-       return !parse(argv, argc);
+       ret = !parse(argv, argc);
+
+       for (p = allocs; p; p = allocs) {
+               allocs = p->next;
+               free(p->s);
+               free(p);
+       }
+       return ret;
 }
-- 
2.3.0

Reply via email to