const char *value)
 {
        rrd_cache_t *rc = NULL;
+       int new_rc = 0;
 
        if (cache != NULL)
                avl_get (cache, filename, (void *) &rc);
                rc->values_num = 0;
                rc->values = NULL;
                rc->first_value = 0;
+               new_rc = 1;
        }
 
        rc->values = (char **) realloc ((void *) rc->values,
                rc->first_value = time (NULL);
 
        /* Insert if this is the first value */
-       if ((cache != NULL) && (rc->values_num == 1))
+       if ((cache != NULL) && (new_rc == 1))
        {
                void *cache_key = strdup (filename);
 
                {
                        syslog (LOG_ERR, "rrdtool plugin: strdup failed: %s",
                                        strerror (errno));
+                       sfree (rc->values[0]);
                        sfree (rc->values);
                        sfree (rc);
                        return (NULL);
        free (argv);
        free (fn);
 
+       /* Free the value list of `rc' */
        for (i = 0; i < rc->values_num; i++)
                free (rc->values[i]);
-
        free (rc->values);
        rc->values = NULL;
        rc->values_num = 0;
        
        for (i = 0; i < keys_num; i++)
        {
-               if (avl_remove (cache, keys[i], NULL, (void *) &rc) != 0)
+               if (avl_remove (cache, keys[i], (void *) &key, (void *) &rc) != 0)
                {
                        DBG ("avl_remove (%s) failed.", keys[i]);
                        continue;
                }
 
-               /* will free `rc' */
                rrd_write_cache_entry (keys[i], rc);
-               sfree (keys[i]); keys[i] = NULL;
+               /* rc's value-list is free's by `rrd_write_cache_entry' */
+               sfree (rc);
+               sfree (key);
+               keys[i] = NULL;
        } /* for (i = 0..keys_num) */
 
        free (keys);
 
        if (cache == NULL)
        {
-               /* will free `rc' */
                rrd_write_cache_entry (filename, rc);
+               /* rc's value-list is free's by `rrd_write_cache_entry' */
+               sfree (rc);
                return (0);
        }
 
 
        DBG ("age (%s) = %i", filename, now - rc->first_value);
 
+       /* `rc' is not free'd here, because we'll likely reuse it. If not, then
+        * the next flush will remove this entry.  */
        if ((now - rc->first_value) >= cache_timeout)
                rrd_write_cache_entry (filename, rc);
 
        if ((now - cache_flush_last) >= cache_flush_timeout)
-       {
                rrd_cache_flush (cache_flush_timeout);
-       }
 
        return (0);
 } /* int rrd_write */
 static int rrd_shutdown (void)
 {
        rrd_cache_flush (-1);
+       if (cache != NULL)
+               avl_destroy (cache);
+       cache = NULL;
 
        return (0);
 } /* int rrd_shutdown */