Fixed several memory leaks. master
authorethereal <ethereal@ethv.net>
Wed, 20 Jan 2016 20:09:32 +0000 (12:09 -0800)
committerethereal <ethereal@ethv.net>
Wed, 20 Jan 2016 20:09:32 +0000 (12:09 -0800)
src/main.c
src/yacjs.c
src/yacjs_dict.c

index 8c2e723..7376a1c 100644 (file)
@@ -5,6 +5,9 @@
 int main() {
     struct yacjs_node *root = yacjs_parse("{\"foo\": \"bar\", \"baz\": [\"a\", \"b\", \"c\"]}");
 
+    yacjs_destroy(root);
+    root = NULL;
+
     FILE *fp = fopen("test/test1.json", "r");
     char buffer[32768];
     int ret = fread(buffer, 1, 32768, fp);
@@ -15,6 +18,9 @@ int main() {
     root = yacjs_parse(buffer);
     printf("root: %p\n", root);
 
+    printf("error: %i\n", yacjs_last_error());
+
+    /*
     struct yacjs_node *node = yacjs_node_array_elem(root, 0);
     node = yacjs_node_dict_get(node, "friends");
     printf("%i friends\n", yacjs_node_array_size(node));
@@ -23,6 +29,8 @@ int main() {
     printf("second friend ID and name: %li, %s\n",
         yacjs_node_num(yacjs_node_dict_get(node, "id")),
         yacjs_node_str(yacjs_node_dict_get(node, "name")));
+*/
+    yacjs_destroy(root);
 
     return 0;
 }
index e33d09e..2952eab 100644 (file)
@@ -8,10 +8,12 @@
 #include "yacjs_dict.h"
 #include "yacjs_u8s.h"
 
+#define zalloc(size) calloc(size, 1)
+
 struct YACJS_NAME(node) {
     enum YACJS_NAME(node_type) type;
     union {
-        const char *string;
+        char *string;
         int64_t number;
         double fp;
         struct {
@@ -82,13 +84,16 @@ void YACJS_NAME(destroy)(struct YACJS_NAME(node) *node) {
 static void destroy_helper(struct YACJS_NAME(node) *node) {
     if(node->type == YACJS_NAME_CAP(NODE_ARRAY)) {
         for(int i = 0; i < node->data.array.entries_count; i ++) {
-            YACJS_NAME(destroy)(node->data.array.entries + i);
+            destroy_helper(node->data.array.entries + i);
         }
         free(node->data.array.entries);
     }
     else if(node->type == YACJS_NAME_CAP(NODE_DICT)) {
         YACJS_NAME(dict_destroy)(node->data.dict,
-            (YACJS_NAME(dict_visitor))destroy_helper);
+            (YACJS_NAME(dict_visitor))YACJS_NAME(destroy));
+    }
+    else if(node->type == YACJS_NAME_CAP(NODE_STRING)) {
+        free(node->data.string);
     }
 }
 
@@ -273,19 +278,19 @@ static struct YACJS_NAME(node) *parse_any(const char **string) {
     if(type == TOKEN_OPENDICT) return parse_dict_contents(string);
     else if(type == TOKEN_OPENARRAY) return parse_array_contents(string);
     else if(type == TOKEN_STRING) {
-        struct YACJS_NAME(node) *build = malloc(sizeof(*build));
+        struct YACJS_NAME(node) *build = zalloc(sizeof(*build));
         build->type = YACJS_NAME_CAP(NODE_STRING);
         build->data.string = U8S_NAME(strndup)(s, len);
         return build;
     }
     else if(type == TOKEN_NUMBER) {
-        struct YACJS_NAME(node) *build = malloc(sizeof(*build));
+        struct YACJS_NAME(node) *build = zalloc(sizeof(*build));
         build->type = YACJS_NAME_CAP(NODE_NUMBER);
         build->data.number = strtoll(s, NULL, 0);
         return build;
     }
     else if(type == TOKEN_FLOAT) {
-        struct YACJS_NAME(node) *build = malloc(sizeof(*build));
+        struct YACJS_NAME(node) *build = zalloc(sizeof(*build));
         build->type = YACJS_NAME_CAP(NODE_FLOAT);
         char *e;
         build->data.fp = strtod(s, &e);
@@ -297,13 +302,13 @@ static struct YACJS_NAME(node) *parse_any(const char **string) {
         return build;
     }
     else if(type == TOKEN_FALSE || type == TOKEN_TRUE) {
-        struct YACJS_NAME(node) *build = malloc(sizeof(*build));
+        struct YACJS_NAME(node) *build = zalloc(sizeof(*build));
         build->type = YACJS_NAME_CAP(NODE_BOOLEAN);
         build->data.boolean = type == TOKEN_TRUE;
         return build;
     }
     else if(type == TOKEN_NULL) {
-        struct YACJS_NAME(node) *build = malloc(sizeof(*build));
+        struct YACJS_NAME(node) *build = zalloc(sizeof(*build));
         build->type = YACJS_NAME_CAP(NODE_NULL);
         return build;
     }
@@ -318,7 +323,7 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) {
     const char *s;
     int len;
 
-    struct YACJS_NAME(node) *result = malloc(sizeof(*result));
+    struct YACJS_NAME(node) *result = zalloc(sizeof(*result));
     result->type = YACJS_NAME_CAP(NODE_DICT);
     result->data.dict = YACJS_NAME(dict_make)();
 
@@ -327,6 +332,7 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) {
         if(type == TOKEN_CLOSEDICT) break;
         // we expect a string here if it's not a closing dictionary
         else if(type != TOKEN_STRING) {
+            YACJS_NAME(destroy)(result);
             return NULL;
         }
 
@@ -335,13 +341,17 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) {
         // expect a colon after the name
         next_token(string, &len, &type);
         if(type != TOKEN_COLON) {
+            YACJS_NAME(destroy)(result);
+            free(ds);
             return NULL;
         }
 
         struct YACJS_NAME(node) *value = parse_any(string);
 
         if(value == NULL) {
-            // TODO: leaked memory
+            YACJS_NAME(destroy)(result);
+            YACJS_NAME(destroy)(value);
+            free(ds);
             return NULL;
         }
 
@@ -356,7 +366,7 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) {
         }
     }
     if(!s) {
-        // TODO: leaked memory
+        YACJS_NAME(destroy)(result);
         return NULL;
     }
 
@@ -368,7 +378,7 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) {
     const char *s;
     int len;
 
-    struct YACJS_NAME(node) *result = malloc(sizeof(*result));
+    struct YACJS_NAME(node) *result = zalloc(sizeof(*result));
     result->type = YACJS_NAME_CAP(NODE_ARRAY);
     result->data.array.entries = NULL;
     result->data.array.entries_size = 0;
@@ -383,7 +393,8 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) {
         }
         struct YACJS_NAME(node) *next = parse_any(string);
         if(!next) {
-            // TODO: leaked memory
+            YACJS_NAME(destroy)(result);
+            YACJS_NAME(destroy)(next);
             return NULL;
         }
 
@@ -395,6 +406,8 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) {
                     * (result->data.array.entries_size * 2 + 1));
             if(nmem == NULL) {
                 last_error = YACJS_NAME_CAP(ERROR_MEMORY);
+                YACJS_NAME(destroy)(result);
+                YACJS_NAME(destroy)(next);
                 return NULL;
             }
 
@@ -413,7 +426,7 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) {
         }
     }
     if(!s) {
-        // TODO: leaked memory
+        YACJS_NAME(destroy)(result);
         return NULL;
     }
 
index c59a40a..4222aa3 100644 (file)
@@ -20,7 +20,7 @@ static char *ystrdup(const char *string);
 static uint64_t string_hash(const char *string);
 static void resize(struct YACJS_NAME(dict) *dict, int newsize);
 static void insert_helper(struct YACJS_NAME(dict) *dict, uint64_t hash,
-    const char *key, void *value);
+    char *key, void *value);
 
 struct YACJS_NAME(dict) *YACJS_NAME(dict_make)() {
     struct YACJS_NAME(dict) *result = malloc(sizeof(*result));
@@ -43,6 +43,7 @@ void YACJS_NAME(dict_destroy)(struct YACJS_NAME(dict) *dict,
             }
         }
     }
+
     free(dict->entries);
     free(dict);
 }
@@ -96,14 +97,15 @@ static void resize(struct YACJS_NAME(dict) *dict, int newsize) {
         insert_helper(dict, oentries[i].key_hash, oentries[i].key,
             oentries[i].value);
     }
+    free(oentries);
 }
 
 static void insert_helper(struct YACJS_NAME(dict) *dict, uint64_t hash,
-    const char *key, void *value) {
+    char *key, void *value) {
     for(int i = 0; i < dict->entries_size; i ++) {
         int in = (i+hash) % dict->entries_size;
         if(dict->entries[in].key) continue;
-        dict->entries[in].key = ystrdup(key);
+        dict->entries[in].key = key;
         dict->entries[in].key_hash = hash;
         dict->entries[in].value = value;
         break;