diff --git a/include/pygit2/types.h b/include/pygit2/types.h
index a2c7f56..9b4d917 100644
--- a/include/pygit2/types.h
+++ b/include/pygit2/types.h
@@ -57,9 +57,16 @@ OBJECT_STRUCT(Blob, git_blob, blob)
 OBJECT_STRUCT(Tag, git_tag, tag)
 OBJECT_STRUCT(Index, git_index, index)
 OBJECT_STRUCT(Walker, git_revwalk, walk)
-OBJECT_STRUCT(Diff, git_diff_list, diff)
 OBJECT_STRUCT(Config, git_config, config)
 
+typedef struct {
+    PyObject_HEAD
+    Repository *repo;
+    git_diff_list *diff;
+    PyObject *diff_changes;
+} Diff;
+
+
 typedef struct {
     PyObject_HEAD
     PyObject *owner; /* Tree or TreeBuilder */
diff --git a/src/pygit2/config.c b/src/pygit2/config.c
index 0983bac..508550c 100644
--- a/src/pygit2/config.c
+++ b/src/pygit2/config.c
@@ -139,7 +139,7 @@ Config_contains(Config *self, PyObject *py_key) {
         return -1;
 
     err = git_config_get_string(&c_value, self->config, c_key);
-
+    free(c_key);
     if (err == GIT_ENOTFOUND)
         return 0;
     if (err < 0) {
@@ -164,15 +164,18 @@ Config_getitem(Config *self, PyObject *py_key)
 
     err = git_config_get_int64(&c_intvalue, self->config, c_key);
     if (err == GIT_OK) {
+        free(c_key);
         return PyInt_FromLong((long)c_intvalue);
     }
 
     err = git_config_get_bool(&c_boolvalue, self->config, c_key);
     if (err == GIT_OK) {
+        free(c_key);
         return PyBool_FromLong((long)c_boolvalue);
     }
 
     err = git_config_get_string(&c_charvalue, self->config, c_key);
+    free(c_key);
     if (err < 0) {
         if (err == GIT_ENOTFOUND) {
             PyErr_SetObject(PyExc_KeyError, py_key);
@@ -189,6 +192,7 @@ Config_setitem(Config *self, PyObject *py_key, PyObject *py_value)
 {
     int err;
     const char *c_key;
+    const char *py_str;
 
     if (!(c_key = py_str_to_c_str(py_key,NULL)))
         return -1;
@@ -203,9 +207,13 @@ Config_setitem(Config *self, PyObject *py_key, PyObject *py_value)
                 (int64_t)PyInt_AsLong(py_value));
     } else {
         py_value = PyObject_Str(py_value);
+        py_str = py_str_to_c_str(py_value,NULL);
         err = git_config_set_string(self->config, c_key,
-                py_str_to_c_str(py_value,NULL));
+                py_str);
+        free(py_str);
     }
+
+    free(c_key);
     if (err < 0) {
         Error_set(err);
         return -1;
diff --git a/src/pygit2/diff.c b/src/pygit2/diff.c
index d010442..5b72439 100644
--- a/src/pygit2/diff.c
+++ b/src/pygit2/diff.c
@@ -48,7 +48,7 @@ static int diff_data_cb(
   const char *content,
   size_t content_len)
 {
-    PyObject *hunks, *data, *tmp;
+    PyObject *hunks, *data;
     Hunk *hunk;
     Py_ssize_t size;
 
@@ -61,14 +61,12 @@ static int diff_data_cb(
     if (hunk == NULL)
       return -1;
 
-    tmp = PyBytes_FromStringAndSize(content, content_len);
-
-    data = Py_BuildValue("(O,i)",
-        tmp,
+    data = Py_BuildValue("(s#,i)",
+        content, content_len,
         line_origin
     );
-
     PyList_Append(hunk->data, data);
+    Py_DECREF(data);
 
     return 0;
 }
@@ -91,6 +89,7 @@ static int diff_hunk_cb(
     if (hunks == NULL) {
         hunks = PyList_New(0);
         PyDict_SetItemString(cb_data, "hunks", hunks);
+        Py_DECREF(hunks);
     }
 
     hunk = (Hunk*)PyType_GenericNew(&HunkType, NULL, NULL);
@@ -125,6 +124,7 @@ static int diff_hunk_cb(
         old_path = malloc(sizeof(char) * len);
         if (old_path == NULL) {
             free(hunk->header);
+            hunk->header = NULL;
             return -1;
         }
 
@@ -153,7 +153,12 @@ static int diff_hunk_cb(
       hunk->data = PyList_New(0);
     }
 
-    PyList_Append(hunks, (PyObject *)hunk);
+    if(PyList_Append(hunks, (PyObject *)hunk) == 0) {
+        Py_DECREF(hunk);
+    }
+    else {
+        return -1;
+    }
 
     return 0;
 };
@@ -169,6 +174,7 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta,
         if(files == NULL) {
             files = PyList_New(0);
             PyDict_SetItemString(cb_data, "files", files);
+            Py_DECREF(files);
         }
 
         file = Py_BuildValue("(s,s,i)",
@@ -177,7 +183,10 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta,
             delta->status
         );
 
-        PyList_Append(files, file);
+        if (PyList_Append(files, file) == 0) {
+            // If success
+            Py_DECREF(file);
+        }
     }
 
     return 0;
@@ -186,18 +195,20 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta,
 PyObject *
 Diff_changes(Diff *self)
 {
-    PyObject *payload;
-    payload = PyDict_New();
 
-    git_diff_foreach(
-        self->diff,
-        payload,
-        &diff_file_cb,
-        &diff_hunk_cb,
-        &diff_data_cb
-    );
+    if (self->diff_changes == NULL){
+        self->diff_changes = PyDict_New();
+        
+        git_diff_foreach(
+            self->diff,
+            self->diff_changes,
+            &diff_file_cb,
+            &diff_hunk_cb,
+            &diff_data_cb
+        );
+    }
 
-    return payload;
+    return PyDict_Copy(self->diff_changes);
 }
 
 static int diff_print_cb(
@@ -227,24 +238,42 @@ Diff_patch(Diff *self)
 static int
 Hunk_init(Hunk *self, PyObject *args, PyObject *kwds)
 {
-      self->old_start = 0;
-      self->old_lines = 0;
+    self->header = NULL;
+    
+    self->old_file = NULL;
+    self->old_start = 0;
+    self->old_lines = 0;
 
-      self->new_start = 0;
-      self->new_lines = 0;
+    self->new_file = NULL;
+    self->new_start = 0;
+    self->new_lines = 0;
 
-      self->data = PyList_New(0);
-      if (self->data == NULL) {
-          Py_XDECREF(self);
-          return -1;
-      }
+    self->old_oid = NULL;
+    self->new_oid = NULL;
+    
+    self->data = PyList_New(0);
+    if (self->data == NULL) {
+        Py_XDECREF(self);
+        return -1;
+    }
 
-      return 0;
+    return 0;
 }
 
 static void
 Hunk_dealloc(Hunk *self)
 {
+    if (self->header != NULL) {
+        free(self->header);
+    }
+    if (self->new_file != NULL) {
+        free(self->new_file);
+    }
+    if (self->old_file != NULL) {
+        free(self->old_file);
+    }
+    Py_XDECREF(self->old_oid);
+    Py_XDECREF(self->new_oid);
     Py_XDECREF(self->data);
     PyObject_Del(self);
 }
@@ -321,6 +350,8 @@ Diff_merge(Diff *self, PyObject *args)
     if (err < 0)
         return Error_set(err);
 
+    Py_XDECREF(self->diff_changes);
+    self->diff_changes = NULL;
     Py_RETURN_NONE;
 }
 
@@ -329,6 +360,7 @@ Diff_dealloc(Diff *self)
 {
     git_diff_list_free(self->diff);
     Py_XDECREF(self->repo);
+    Py_XDECREF(self->diff_changes);
     PyObject_Del(self);
 }
 
diff --git a/src/pygit2/index.c b/src/pygit2/index.c
index 8681bd3..cc2fd10 100644
--- a/src/pygit2/index.c
+++ b/src/pygit2/index.c
@@ -214,6 +214,7 @@ Index_get_position(Index *self, PyObject *value)
         free(path);
         return -1;
     }
+    free(path);
     return idx;
 }
 
@@ -227,14 +228,16 @@ Index_contains(Index *self, PyObject *value)
     if (!path)
         return -1;
     idx = git_index_find(self->index, path);
-    if (idx == GIT_ENOTFOUND)
+    if (idx == GIT_ENOTFOUND) {
+        free(path);
         return 0;
+    }
     if (idx < 0) {
         Error_set_str(idx, path);
         free(path);
         return -1;
     }
-
+    free(path);
     return 1;
 }
 
@@ -339,6 +342,7 @@ Index_read_tree(Index *self, PyObject *value)
         return Error_set(err);
 
     err = git_index_read_tree(self->index, tree);
+    git_tree_free(tree);
     if (err < 0)
         return Error_set(err);
 
diff --git a/src/pygit2/repository.c b/src/pygit2/repository.c
index 0fcfbb7..a150253 100644
--- a/src/pygit2/repository.c
+++ b/src/pygit2/repository.c
@@ -166,6 +166,7 @@ Repository_head(Repository *self)
 {
     git_reference *head;
     const git_oid *oid;
+    PyObject *pyobj;
     int err;
 
     err = git_repository_head(&head, self->repo);
@@ -179,8 +180,9 @@ Repository_head(Repository *self)
     }
 
     oid = git_reference_oid(head);
-
-    return lookup_object(self, oid, GIT_OBJ_COMMIT);
+    pyobj = lookup_object(self, oid, GIT_OBJ_COMMIT);
+    git_reference_free(head);
+    return pyobj; 
 }
 
 
@@ -202,7 +204,7 @@ Repository_revparse_single(Repository *self, PyObject *py_spec)
 {
     git_object *c_obj;
     char *c_spec;
-		char *encoding = "ascii";
+    char *encoding = "ascii";
     int err;
 
     /* 1- Get the C revision spec */
@@ -212,12 +214,14 @@ Repository_revparse_single(Repository *self, PyObject *py_spec)
 
     /* 2- Lookup */
     err = git_revparse_single(&c_obj, self->repo, c_spec);
+    
     if (err < 0)  {
         PyObject *err_obj = Error_set_str(err, c_spec);
         free(c_spec);
         return err_obj;
     }
-
+    free(c_spec);
+    
     return wrap_object(c_obj, self);
 }
 
@@ -635,7 +639,7 @@ Repository_lookup_reference(Repository *self, PyObject *py_name)
         free(c_name);
         return err_obj;
     }
-
+    free(c_name);
     /* 3- Make an instance of Reference and return it */
     return wrap_reference(c_reference);
 }
diff --git a/src/pygit2/tree.c b/src/pygit2/tree.c
index 0127c08..fdd20a7 100644
--- a/src/pygit2/tree.c
+++ b/src/pygit2/tree.c
@@ -43,6 +43,7 @@ void
 TreeEntry_dealloc(TreeEntry *self)
 {
     Py_XDECREF(self->owner);
+    git_tree_entry_free(self->entry);
     PyObject_Del(self);
 }
 
@@ -231,7 +232,7 @@ Tree_getitem_by_index(Tree *self, PyObject *py_index)
         PyErr_SetObject(PyExc_IndexError, py_index);
         return NULL;
     }
-    return wrap_tree_entry(entry, self);
+    return wrap_tree_entry(git_tree_entry_dup(entry), self);
 }
 
 TreeEntry *
@@ -261,6 +262,7 @@ Tree_getitem(Tree *self, PyObject *value)
     if (err < 0)
         return (TreeEntry*)Error_set(err);
 
+    // git_tree_entry_dup is already done in git_tree_entry_bypath
     return wrap_tree_entry(entry, self);
 }
 
@@ -305,10 +307,10 @@ Tree_diff_tree(Tree *self, PyObject *args)
 
     py_diff = PyObject_New(Diff, &DiffType);
     if (py_diff) {
-        Py_INCREF(py_diff);
         Py_INCREF(self->repo);
         py_diff->repo = self->repo;
         py_diff->diff = diff;
+        py_diff->diff_changes = NULL;
     }
 
     return (PyObject*)py_diff;
@@ -527,7 +529,7 @@ TreeIter_iternext(TreeIter *self)
         return NULL;
 
     self->i += 1;
-    return (TreeEntry*)wrap_tree_entry(tree_entry, self->owner);
+    return (TreeEntry*)wrap_tree_entry(git_tree_entry_dup(tree_entry), self->owner);
 }
 
 PyTypeObject TreeIterType = {