소스 검색

Clear memory leaks and bad pointers.

Stefano Cossu 5 년 전
부모
커밋
46af4d3311
6개의 변경된 파일143개의 추가작업 그리고 32개의 파일을 삭제
  1. 3 5
      include/graph.h
  2. 2 0
      include/triple.h
  3. 22 20
      src/graph.c
  4. 1 0
      src/index.c
  5. 11 7
      src/term.c
  6. 104 0
      test/test_graph.c

+ 3 - 5
include/graph.h

@@ -14,7 +14,7 @@ typedef enum LSUP_store_type {
 typedef struct LSUP_Graph {
     LSUP_store_type store_type;
     LSUP_Keyset *keys;
-    const LSUP_Term *uri;
+    LSUP_Term *uri;
     LSUP_Index *idx;
 } LSUP_Graph;
 
@@ -26,13 +26,11 @@ typedef void (*lookup_callback_fn_t)(
 
 int
 LSUP_graph_init(
-        LSUP_Graph *gr, size_t capacity, const LSUP_Term *uri,
+        LSUP_Graph *gr, size_t capacity, char *uri_str,
         LSUP_store_type store_type);
 
 LSUP_Graph *
-LSUP_graph_new(
-        size_t capacity, const LSUP_Term *uri,
-        LSUP_store_type store_type);
+LSUP_graph_new(size_t capacity, char *uri_str, LSUP_store_type store_type);
 
 bool
 LSUP_graph_contains(const LSUP_Graph *gr, const LSUP_Triple *t);

+ 2 - 0
include/triple.h

@@ -11,3 +11,5 @@ typedef struct LSUP_SerTriple {
     LSUP_SerTerm *p;
     LSUP_SerTerm *o;
 } LSUP_SerTriple;
+
+// TODO Add constructors and destructors with term type checks.

+ 22 - 20
src/graph.c

@@ -10,12 +10,10 @@ size_t LSUP_graph_capacity(LSUP_Graph *gr);
 
 int
 LSUP_graph_init(
-        LSUP_Graph *gr, size_t capacity, const LSUP_Term *uri,
+        LSUP_Graph *gr, size_t capacity, char *uri_str,
         LSUP_store_type store_type)
 {
-    if (uri->type != LSUP_TERM_URI)
-        return -1;
-    gr->uri = uri;
+    gr->uri = LSUP_term_new(LSUP_TERM_URI, uri_str, NULL, NULL);
 
     gr->keys = LSUP_keyset_new(capacity, .75);
 
@@ -36,14 +34,12 @@ LSUP_graph_init(
 
 
 LSUP_Graph *
-LSUP_graph_new(
-        size_t capacity, const LSUP_Term *uri,
-        LSUP_store_type store_type)
+LSUP_graph_new(size_t capacity, char *uri_str, LSUP_store_type store_type)
 {
     LSUP_Graph *gr;
     CRITICAL(gr = malloc(sizeof(LSUP_Graph)));
 
-    LSUP_graph_init(gr, capacity, uri, store_type);
+    LSUP_graph_init(gr, capacity, uri_str, store_type);
 
     return gr;
 }
@@ -58,22 +54,27 @@ LSUP_graph_add(LSUP_Graph *gr, LSUP_Triple data[], size_t data_size)
     if (gr->keys->capacity < gr->keys->free_i + data_size)
         LSUP_keyset_resize(gr->keys, gr->keys->free_i + data_size);
 
-    LSUP_SerTerm **sterms = malloc(
-            sizeof(LSUP_SerTerm) * 3 * LSUP_keyset_size(gr->keys));
-
     for (size_t i = 0; i < data_size; i++) {
-        LSUP_term_serialize(data[i].s, sterms[i]);
-        LSUP_term_serialize(data[i].p, sterms[i] + 1);
-        LSUP_term_serialize(data[i].o, sterms[i] + 2);
+        LSUP_SerTerm sspo[3];
 
-        LSUP_Key sk = LSUP_sterm_to_key(sterms[i]);
-        LSUP_Key pk = LSUP_sterm_to_key(sterms[i] + 1);
-        LSUP_Key ok = LSUP_sterm_to_key(sterms[i] + 2);
+        LSUP_term_serialize(data[i].s, sspo);
+        LSUP_term_serialize(data[i].p, sspo + 1);
+        LSUP_term_serialize(data[i].o, sspo + 2);
+
+        LSUP_Key sk = LSUP_sterm_to_key(sspo);
+        LSUP_Key pk = LSUP_sterm_to_key(sspo + 1);
+        LSUP_Key ok = LSUP_sterm_to_key(sspo + 2);
 
         // Add terms to index.
-        LSUP_index_add_pair(gr->idx, sk, sterms[i]);
-        LSUP_index_add_pair(gr->idx, pk, sterms[i] + 1);
-        LSUP_index_add_pair(gr->idx, ok, sterms[i] + 2);
+        // TODO Optimize. This copies sterm data twice: once to serialize,
+        // once to add to index.
+        LSUP_index_add_pair(gr->idx, sk, sspo);
+        LSUP_index_add_pair(gr->idx, pk, sspo + 1);
+        LSUP_index_add_pair(gr->idx, ok, sspo + 2);
+
+        LSUP_buffer_done(sspo);
+        LSUP_buffer_done(sspo + 1);
+        LSUP_buffer_done(sspo + 2);
 
         // Add triple.
         LSUP_TripleKey trp = {sk, pk, ok};
@@ -101,6 +102,7 @@ void
 LSUP_graph_free(LSUP_Graph *gr)
 {
     if(LIKELY(gr != NULL)) {
+        LSUP_term_free(gr->uri);
         LSUP_keyset_free(gr->keys);
         LSUP_index_free(gr->idx);
         free(gr);

+ 1 - 0
src/index.c

@@ -87,6 +87,7 @@ void LSUP_index_free(LSUP_Index *idx)
 {
     for (size_t i = 0; i < idx->free_i; i++) {
         LSUP_buffer_done(idx->entries[i].val);
+        free(idx->entries[i].val);
     }
 
     free(idx->entries);

+ 11 - 7
src/term.c

@@ -172,21 +172,25 @@ bool LSUP_term_equals(const LSUP_Term *term1, const LSUP_Term *term2)
 
 void LSUP_term_done(LSUP_Term *term)
 {
-    if (term->data != NULL)
+    if (LIKELY(term->data != NULL)) {
         free(term->data);
-    else
-        TRACE(STR, "Term data is NULL!");
+        term->data = NULL;
+    }
 
-    if (term->datatype != NULL)
+    if (term->datatype != NULL) {
         free(term->datatype);
+        term->datatype = NULL;
+    }
 }
 
 
 void LSUP_term_free(LSUP_Term *term)
 {
-    TRACE(STR, "Freeing term.");
-    LSUP_term_done(term);
-    free(term);
+    if (LIKELY(term != NULL)) {
+        LSUP_term_done(term);
+        free(term);
+        term = NULL;
+    }
 }
 
 

+ 104 - 0
test/test_graph.c

@@ -1,7 +1,111 @@
 #include "test.h"
+#include "graph.h"
+
+#define NUM_TRP 10
+
+static int _create_triples(LSUP_Triple *trp)
+{
+    trp[0].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:0", NULL, NULL);
+    trp[0].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:0", NULL, NULL);
+    trp[0].o = LSUP_term_new(LSUP_TERM_URI, "urn:o:0", NULL, NULL);
+
+    trp[1].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:1", NULL, NULL);
+    trp[1].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:1", NULL, NULL);
+    trp[1].o = LSUP_term_new(LSUP_TERM_URI, "urn:o:1", NULL, NULL);
+
+    trp[2].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:2", NULL, NULL);
+    trp[2].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:2", NULL, NULL);
+    trp[2].o = LSUP_term_new(LSUP_TERM_URI, "urn:o:2", NULL, NULL);
+
+    trp[3].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:0", NULL, NULL);
+    trp[3].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:1", NULL, NULL);
+    trp[3].o = LSUP_term_new(LSUP_TERM_URI, "urn:o:2", NULL, NULL);
+
+    trp[4].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:0", NULL, NULL);
+    trp[4].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:2", NULL, NULL);
+    trp[4].o = LSUP_term_new(
+            LSUP_TERM_LITERAL, "String 1", NULL, NULL);
+
+    trp[5].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:0", NULL, NULL);
+    trp[5].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:5", NULL, NULL);
+    trp[5].o = LSUP_term_new(
+            LSUP_TERM_LITERAL, "String 2", "xsd:string", NULL);
+
+    trp[6].s = LSUP_term_new(LSUP_TERM_URI, "urn:s:1", NULL, NULL);
+    trp[6].p = LSUP_term_new(LSUP_TERM_URI, "urn:p:6", NULL, NULL);
+    trp[6].o = LSUP_term_new(
+            LSUP_TERM_LITERAL, "String 3", "xsd:string", "es-ES");
+
+    // Let's reuse pointers. They should 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 2"^^xsd:string
+
+    // Duplicate of trp[7]
+    trp[8].s = trp[0].s;
+    trp[8].p = trp[2].p;
+    trp[8].o = trp[5].o;
+
+    // Duplicate of trp[7] from different pointers with same value.
+    trp[9].s = trp[5].s;
+    trp[9].p = trp[4].p;
+    trp[9].o = trp[5].o;
+
+    return 0;
+}
+
+
+static void _free_triples(LSUP_Triple *trp)
+{
+    // Last three triples are second pointers.
+    for(int i=0; i < NUM_TRP - 3; i++) {
+        LSUP_term_free(trp[i].s);
+        LSUP_term_free(trp[i].p);
+        LSUP_term_free(trp[i].o);
+    }
+
+    free(trp);
+}
+
+
+static int test_graph_heap()
+{
+    LSUP_Graph *gr = LSUP_graph_new(10, "urn:gr:1", LSUP_STORE_MEM);
+
+    ASSERT(strcmp(gr->uri->data, "urn:gr:1") == 0, "Graph URI mismatch!");
+    EXPECT_INT_EQ(LSUP_graph_capacity(gr), 10);
+    EXPECT_INT_EQ(LSUP_graph_size(gr), 0);
+
+    LSUP_graph_free(gr);
+
+    return 0;
+}
+
+
+static int test_graph_add()
+{
+    LSUP_Triple *trp = malloc(NUM_TRP * sizeof(LSUP_Triple));
+    _create_triples(trp);
+
+    LSUP_Graph *gr = LSUP_graph_new(NUM_TRP + 2, "urn:gr:2", LSUP_STORE_MEM);
+
+    LSUP_graph_add(gr, trp, NUM_TRP);
+
+    _free_triples(trp); // gr takes ownership of data.
+
+    EXPECT_INT_EQ(LSUP_graph_capacity(gr), NUM_TRP + 2);
+    EXPECT_INT_EQ(LSUP_graph_size(gr), 8);
+
+    LSUP_graph_free(gr);
+
+    return 0;
+}
+
 
 int graph_tests()
 {
+    RUN(test_graph_heap);
+    RUN(test_graph_add);
     return 0;
 }