Browse Source

Resolve all mem leaks.

Stefano Cossu 3 years ago
parent
commit
533a4fe77d
7 changed files with 111 additions and 93 deletions
  1. 10 0
      Makefile
  2. 2 1
      include/buffer.h
  3. 9 6
      src/graph.c
  4. 10 7
      src/term.c
  5. 1 1
      test/assets.h
  6. 9 8
      test/test_store_mdb.c
  7. 70 70
      test/test_term.c

+ 10 - 0
Makefile

@@ -33,6 +33,16 @@ test:
 		$(SRC) test.c \
 		-o bin/test
 
+
+valgrind:
+	valgrind \
+	--leak-check=full --show-leak-kinds=all --track-origins=yes \
+	./bin/test
+
+
+memcheck: test valgrind
+
+
 profile:
 	$(CC) \
 		$(CFLAGS)

+ 2 - 1
include/buffer.h

@@ -46,7 +46,8 @@ LSUP_buffer_init (LSUP_Buffer *buf, const size_t size, const void *data);
  *
  * @param size[in] Length of the data.
  *
- * @param data[in] Optional data to initially populate the object with.
+ * @param data[in] Optional data to initially populate the object with. If
+ *  NULL, the buffer data are garbage.
  *
  * @return LSUP_Buffer pointer. It must be freed with #LSUP_buffer_free. NULL
  *  on error.

+ 9 - 6
src/graph.c

@@ -76,7 +76,7 @@ graph_iter_next_buffer (GraphIterator *it, LSUP_SerTriple *sspo);
 
 
 /* Atexit functions. */
-void ctx_cleanup() { LSUP_buffer_done (default_ctx); }
+void ctx_cleanup() { LSUP_buffer_free (default_ctx); }
 
 
 static inline bool is_null_trp (const LSUP_TripleKey *trp)
@@ -318,14 +318,17 @@ LSUP_graph_add(
 
         LSUP_Buffer *sc = LSUP_buffer_new_from_term (gr->uri);
         LSUP_MDBIterator *it = LSUP_mdbstore_add_init (gr->mdb_store, sc);
-        LSUP_buffer_done (sc);
+        LSUP_buffer_free (sc);
 
         // Serialize and insert RDF triples.
         if (trp_ct > 0) {
-            for (size_t i = 0; i < trp_ct; i++) {
-                LSUP_SerTriple *sspo = LSUP_striple_new_from_triple (trp + i);
+            LSUP_SerTriple *sspo = LSUP_striple_new(
+                    BUF_DUMMY, BUF_DUMMY, BUF_DUMMY);
 
+            for (size_t i = 0; i < trp_ct; i++) {
                 TRACE ("Inserting triple #%lu\n", i);
+
+                LSUP_triple_serialize (trp + i, sspo);
                 LSUP_rc db_rc = LSUP_mdbstore_add_iter (it, sspo);
 
                 if (LIKELY (db_rc == LSUP_OK)) {
@@ -333,10 +336,10 @@ LSUP_graph_add(
                     (*inserted) ++;
                 }
 
-                LSUP_striple_free (sspo);
-
                 if (UNLIKELY (db_rc < 0)) return db_rc;
             }
+
+            LSUP_striple_free (sspo);
         }
 
         // Insert serialized triples.

+ 10 - 7
src/term.c

@@ -23,13 +23,13 @@ LSUP_term_new (
         LSUP_term_type type, const char *data, char *datatype, char *lang)
 {
     LSUP_Term *term;
-    term = malloc (sizeof (*term));
+    term = calloc (1, sizeof (*term));
     if (UNLIKELY (!term)) return NULL;
 
-    term->data = NULL;
-    term->datatype = NULL;
+    // If undefined, just set the type.
+    if (type == LSUP_TERM_UNDEFINED) term->type = type;
 
-    if (UNLIKELY (LSUP_term_init (
+    else if (UNLIKELY (LSUP_term_init (
                     term, type, data, datatype, lang) != LSUP_OK)) {
         free (term);
         return NULL;
@@ -74,9 +74,11 @@ LSUP_term_init(
         LSUP_Term *term, LSUP_term_type type,
         const char *data, char *datatype, char *lang)
 {
+    // This can never be LSUP_TERM_UNDEFINED.
+    if (!data) return LSUP_VALUE_ERR;
     term->type = type;
-    if (data == NULL) return LSUP_VALUE_ERR;
 
+    // Validate URI.
     if (term->type == LSUP_TERM_URI) {
         if (UNLIKELY (!ptn_init)) {
             assert (regcomp (&ptn, URI_REGEX_STR, REG_EXTENDED) == 0);
@@ -92,16 +94,17 @@ LSUP_term_init(
     }
 
     char *data_tmp = realloc (term->data, strlen (data) + 1);
-    if (UNLIKELY (!data_tmp)) return ENOMEM;
+    if (UNLIKELY (!data_tmp)) return LSUP_MEM_ERR;
     term->data = data_tmp;
     strcpy (term->data, data);
 
     if (datatype) {
         data_tmp = realloc (term->datatype, strlen (datatype) + 1);
-        if (UNLIKELY (!data_tmp)) return ENOMEM;
+        if (UNLIKELY (!data_tmp)) return LSUP_MEM_ERR;
         term->datatype = data_tmp;
         strcpy (term->datatype, datatype);
     } else {
+        free (term->datatype);
         term->datatype = NULL;
     }
     if (lang) {

+ 1 - 1
test/assets.h

@@ -81,7 +81,7 @@ LSUP_Triple *create_triples()
     trp[6].o = LSUP_term_new(
             LSUP_TERM_LITERAL, "String 1", "xsd:string", "es-ES");
 
-    // Let's reuse pointers. Do not double-free.
+    // Unique triple from reused pointers. Do not double-free.
     trp[7].s = trp[0].s; // <urn:s:0>
     trp[7].p = trp[2].p; // <urn:p:2>
     trp[7].o = trp[5].o; // "String 1"^^xsd:string

+ 9 - 8
test/test_store_mdb.c

@@ -85,9 +85,9 @@ static int test_triple_store()
     }
 
     for (int i = 0; i < NUM_TRP; i++) {
-        LSUP_buffer_done (ser_trp[i].s);
-        LSUP_buffer_done (ser_trp[i].p);
-        LSUP_buffer_done (ser_trp[i].o);
+        LSUP_buffer_free (ser_trp[i].s);
+        LSUP_buffer_free (ser_trp[i].p);
+        LSUP_buffer_free (ser_trp[i].o);
     }
 
     LSUP_mdbstore_free (store);
@@ -286,16 +286,17 @@ static int test_quad_store()
     }
 
     for (int i = 0; i < NUM_TRP; i++) {
-        LSUP_buffer_done (ser_trp[i].s);
-        LSUP_buffer_done (ser_trp[i].p);
-        LSUP_buffer_done (ser_trp[i].o);
+        LSUP_buffer_free (ser_trp[i].s);
+        LSUP_buffer_free (ser_trp[i].p);
+        LSUP_buffer_free (ser_trp[i].o);
     }
 
     LSUP_term_free (ctx1);
     LSUP_term_free (ctx2);
     LSUP_term_free (ctx3);
-    LSUP_buffer_done (sc1);
-    LSUP_buffer_done (sc2);
+    LSUP_buffer_free (sc1);
+    LSUP_buffer_free (sc2);
+    LSUP_buffer_free (sc3);
     free_triples (trp);
 
     LSUP_mdbstore_free (store);

+ 70 - 70
test/test_term.c

@@ -7,69 +7,69 @@ static int test_term_new()
     char *datatype = "xsd:string";
     char *lang = "en-US";
 
-    TRACE(STR, "Test term, heap-allocated.");
-    LSUP_Term *term = LSUP_term_new(LSUP_TERM_LITERAL, data, datatype, lang);
+    TRACE (STR, "Test term, heap-allocated.");
+    LSUP_Term *term = LSUP_term_new (LSUP_TERM_LITERAL, data, datatype, lang);
 
-    TRACE("Term data: %s", term->data);
-    EXPECT_STR_EQ(term->data, data);
-    EXPECT_STR_EQ(term->datatype, datatype);
-    EXPECT_STR_EQ(term->lang, lang);
+    TRACE ("Term data: %s", term->data);
+    EXPECT_STR_EQ (term->data, data);
+    EXPECT_STR_EQ (term->datatype, datatype);
+    EXPECT_STR_EQ (term->lang, lang);
 
-    TRACE(STR, "Reset term.\n");
+    TRACE (STR, "Reset term.\n");
 
     char *uri_data = "urn:id:2144564356";
-    LSUP_term_init(term, LSUP_TERM_URI, uri_data, NULL, NULL);
-    EXPECT_STR_EQ(term->data, uri_data);
+    LSUP_term_init (term, LSUP_TERM_URI, uri_data, NULL, NULL);
+    EXPECT_STR_EQ (term->data, uri_data);
 
-    LSUP_term_free(term);
+    LSUP_term_free (term);
 
     return 0;
 }
 
 static int test_term_serialize_deserialize()
 {
-    LSUP_Term *uri = LSUP_uri_new("http://hello.org");
-    LSUP_Term *lit = LSUP_term_new(LSUP_TERM_LITERAL, "hello", NULL, NULL);
-    LSUP_Term *tlit = LSUP_term_new(LSUP_TERM_LITERAL, "hello", "xsd:string", NULL);
-    LSUP_Term *tllit = LSUP_term_new(LSUP_TERM_LITERAL, "hello", "xsd:string", "en-US");
+    LSUP_Term *uri = LSUP_uri_new ("http://hello.org");
+    LSUP_Term *lit = LSUP_term_new (LSUP_TERM_LITERAL, "hello", NULL, NULL);
+    LSUP_Term *tlit = LSUP_term_new (LSUP_TERM_LITERAL, "hello", "xsd:string", NULL);
+    LSUP_Term *tllit = LSUP_term_new (LSUP_TERM_LITERAL, "hello", "xsd:string", "en-US");
 
     LSUP_Buffer *sterm = BUF_DUMMY;
-    LSUP_Term *dsterm = malloc (sizeof (*dsterm));
-
-    LSUP_term_serialize(uri, sterm);
-    TRACE("%s", "Serialized URI: ");
-    LSUP_buffer_print(sterm);
-    TRACE("%s", "\n");
-    LSUP_term_deserialize(sterm, dsterm);
-    ASSERT(LSUP_term_equals(dsterm, uri), "URI serialization error!");
-    LSUP_term_free(uri);
-
-    LSUP_term_serialize(lit, sterm);
-    TRACE("%s", "Serialized literal: ");
-    LSUP_buffer_print(sterm);
-    TRACE("%s", "\n");
-    LSUP_term_deserialize(sterm, dsterm);
-    ASSERT(LSUP_term_equals(dsterm, lit), "lit serialization error!");
-    LSUP_term_free(lit);
-
-    LSUP_term_serialize(tlit, sterm);
-    TRACE("%s", "Serialized typed literal: ");
-    LSUP_buffer_print(sterm);
-    TRACE("%s", "\n");
-    LSUP_term_deserialize(sterm, dsterm);
-    ASSERT(LSUP_term_equals(dsterm, tlit), "tlit serialization error!");
-    LSUP_term_free(tlit);
-
-    LSUP_term_serialize(tllit, sterm);
-    TRACE("%s", "Serialized typed and language-tagged URI: ");
-    LSUP_buffer_print(sterm);
-    TRACE("%s", "\n");
-    LSUP_term_deserialize(sterm, dsterm);
-    ASSERT(LSUP_term_equals(dsterm, tllit), "URI serialization error!");
-    LSUP_term_free(tllit);
-
-    LSUP_term_free(dsterm);
-    LSUP_buffer_free(sterm);
+    LSUP_Term *dsterm = TERM_DUMMY;
+
+    LSUP_term_serialize (uri, sterm);
+    TRACE ("%s", "Serialized URI: ");
+    LSUP_buffer_print (sterm);
+    TRACE ("%s", "\n");
+    LSUP_term_deserialize (sterm, dsterm);
+    ASSERT (LSUP_term_equals (dsterm, uri), "URI serialization error!");
+    LSUP_term_free (uri);
+
+    LSUP_term_serialize (lit, sterm);
+    TRACE ("%s", "Serialized literal: ");
+    LSUP_buffer_print (sterm);
+    TRACE ("%s", "\n");
+    LSUP_term_deserialize (sterm, dsterm);
+    ASSERT (LSUP_term_equals (dsterm, lit), "lit serialization error!");
+    LSUP_term_free (lit);
+
+    LSUP_term_serialize (tlit, sterm);
+    TRACE ("%s", "Serialized typed literal: ");
+    LSUP_buffer_print (sterm);
+    TRACE ("%s", "\n");
+    LSUP_term_deserialize (sterm, dsterm);
+    ASSERT (LSUP_term_equals (dsterm, tlit), "tlit serialization error!");
+    LSUP_term_free (tlit);
+
+    LSUP_term_serialize (tllit, sterm);
+    TRACE ("%s", "Serialized typed and language-tagged URI: ");
+    LSUP_buffer_print (sterm);
+    TRACE ("%s", "\n");
+    LSUP_term_deserialize (sterm, dsterm);
+    ASSERT (LSUP_term_equals (dsterm, tllit), "URI serialization error!");
+    LSUP_term_free (tllit);
+
+    LSUP_term_free (dsterm);
+    LSUP_buffer_free (sterm);
 
     return 0;
 }
@@ -77,8 +77,8 @@ static int test_term_serialize_deserialize()
 
 static int test_term_to_key()
 {
-    LSUP_Term *uri = LSUP_uri_new("http://hello.org");
-    LSUP_Term *lit = LSUP_term_new(LSUP_TERM_LITERAL, "hello", NULL, NULL);
+    LSUP_Term *uri = LSUP_uri_new ("http://hello.org");
+    LSUP_Term *lit = LSUP_term_new (LSUP_TERM_LITERAL, "hello", NULL, NULL);
     LSUP_Term *tlit = LSUP_term_new(
             LSUP_TERM_LITERAL, "hello", "xsd:string", NULL);
     LSUP_Term *tllit1 = LSUP_term_new(
@@ -86,32 +86,32 @@ static int test_term_to_key()
     LSUP_Term *tllit2 = LSUP_term_new(
             LSUP_TERM_LITERAL, "hello", "xsd:string", "en-GB");
 
-    LSUP_Key uri_key = LSUP_term_to_key(uri);
-    LSUP_Key lit_key = LSUP_term_to_key(lit);
-    LSUP_Key tlit_key = LSUP_term_to_key(tlit);
-    LSUP_Key tllit1_key = LSUP_term_to_key(tllit1);
-    LSUP_Key tllit2_key = LSUP_term_to_key(tllit2);
+    LSUP_Key uri_key = LSUP_term_to_key (uri);
+    LSUP_Key lit_key = LSUP_term_to_key (lit);
+    LSUP_Key tlit_key = LSUP_term_to_key (tlit);
+    LSUP_Key tllit1_key = LSUP_term_to_key (tllit1);
+    LSUP_Key tllit2_key = LSUP_term_to_key (tllit2);
 
-    ASSERT(uri_key != lit_key, "URI key conflict!");
-    ASSERT(lit_key != tlit_key, "URI key conflict!");
-    ASSERT(lit_key != tllit1_key, "URI key conflict!");
-    ASSERT(tlit_key != tllit1_key, "URI key conflict!");
-    ASSERT(tllit1_key != tllit2_key, "URI key conflict!");
+    ASSERT (uri_key != lit_key, "URI key conflict!");
+    ASSERT (lit_key != tlit_key, "URI key conflict!");
+    ASSERT (lit_key != tllit1_key, "URI key conflict!");
+    ASSERT (tlit_key != tllit1_key, "URI key conflict!");
+    ASSERT (tllit1_key != tllit2_key, "URI key conflict!");
 
-    LSUP_term_free(uri);
-    LSUP_term_free(lit);
-    LSUP_term_free(tlit);
-    LSUP_term_free(tllit1);
-    LSUP_term_free(tllit2);
+    LSUP_term_free (uri);
+    LSUP_term_free (lit);
+    LSUP_term_free (tlit);
+    LSUP_term_free (tllit1);
+    LSUP_term_free (tllit2);
 
     return 0;
 }
 
 
 int term_tests() {
-    RUN(test_term_new);
-    RUN(test_term_serialize_deserialize);
-    RUN(test_term_to_key);
+    RUN (test_term_new);
+    RUN (test_term_serialize_deserialize);
+    RUN (test_term_to_key);
 
     return 0;
 }