From 0a5aade7f4eec887c8a0dc5b4922c20feaf0185b Mon Sep 17 00:00:00 2001 From: Sergei Shilovsky Date: Sun, 2 Mar 2014 20:14:52 +0400 Subject: [PATCH 1/2] append extra wrapping brackets at kv_pushp --- kvec.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kvec.h b/kvec.h index 676be8b..10f1c5b 100644 --- a/kvec.h +++ b/kvec.h @@ -76,10 +76,10 @@ int main() { (v).a[(v).n++] = (x); \ } while (0) -#define kv_pushp(type, v) (((v).n == (v).m)? \ +#define kv_pushp(type, v) ((((v).n == (v).m)? \ ((v).m = ((v).m? (v).m<<1 : 2), \ (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ - : 0), ((v).a + ((v).n++)) + : 0), ((v).a + ((v).n++))) #define kv_a(type, v, i) (((v).m <= (size_t)(i)? \ ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \ From a835651c08ab7270636bf4d097e9b3e2d67e9f73 Mon Sep 17 00:00:00 2001 From: John Marshall Date: Wed, 12 Mar 2014 14:33:12 +0000 Subject: [PATCH 2/2] Add ks_release() to kstring.h Using this function is a more explicit way of transferring ownership than just "foo = str.s"; the latter leaves room for readers to wonder whether a subsequent "free(str.s)" has been forgotten. --- kstring.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/kstring.h b/kstring.h index 0e654cb..2567efc 100644 --- a/kstring.h +++ b/kstring.h @@ -49,9 +49,8 @@ * kstring_t str = { 0, 0, NULL }; * kstring_t str; ...; str.l = str.m = 0; str.s = NULL; * and either ownership of the underlying buffer should be given away before - * the object disappears (i.e., the str.s pointer copied and something else - * responsible for freeing it), or the kstring_t should be destroyed with - * free(str.s); */ + * the object disappears (see ks_release() below) or the kstring_t should be + * destroyed with free(str.s); */ #ifndef KSTRING_T #define KSTRING_T kstring_t typedef struct __kstring_t { @@ -111,6 +110,18 @@ static inline size_t ks_len(kstring_t *s) return s->l; } +// Give ownership of the underlying buffer away to something else (making +// that something else responsible for freeing it), leaving the kstring_t +// empty and ready to be used again, or ready to go out of scope without +// needing free(str.s) to prevent a memory leak. +static inline char *ks_release(kstring_t *s) +{ + char *ss = s->s; + s->l = s->m = 0; + s->s = NULL; + return ss; +} + static inline int kputsn(const char *p, int l, kstring_t *s) { if (s->l + l + 1 >= s->m) {