Subject: [patch] possible memory leak in diff.c::diff_free_filepair()

From: Yasushi SHOJI <[email-masked]>
Date: Sat, 13 Aug 2005 19:58:56 +0900

Hi all,

When I run git-diff-tree on big change, it seems the command eats so
much memory.  so I just put git under valgrind to see what's going on.

here is the output:

==26475== 63816 bytes in 766 blocks are definitely lost in loss record 7 of 7
==26475==    at 0x1B8FF896: malloc (vg_replace_malloc.c:149)
==26475==    by 0x805203B: alloc_filespec (diff.c:214)
==26475==    by 0x80528C5: diff_addremove (diff.c:1141)
==26475==    by 0x8049C7A: show_file (diff-tree.c:97)
==26475==    by 0x8049D63: show_file (diff-tree.c:206)
==26475==    by 0x8049D63: show_file (diff-tree.c:206)
==26475==    by 0x8049D63: show_file (diff-tree.c:206)
==26475==    by 0x8049EB3: diff_tree (diff-tree.c:118)
==26475==    by 0x804A12E: diff_tree_sha1 (diff-tree.c:260)
==26475==    by 0x804A06E: diff_tree (diff-tree.c:139)
==26475==    by 0x804A12E: diff_tree_sha1 (diff-tree.c:260)
==26475==    by 0x804A06E: diff_tree (diff-tree.c:139)
==26475== 
==26475== LEAK SUMMARY:
==26475==    definitely lost: 63816 bytes in 766 blocks.
==26475==      possibly lost: 0 bytes in 0 blocks.
==26475==    still reachable: 351 bytes in 6 blocks.
==26475==         suppressed: 0 bytes in 0 blocks.

diff_free_filespec_data() doesn't free diff_filespec itself.  is this
because in merge_broken() filespec itself is used but fliespec data
need to be freed?

so I've put one more function, diff_free_filespec(), between
diff_free_filepare() and diff_free_filespec_data() call-chain.

result is:

==27983== LEAK SUMMARY:
==27983==    definitely lost: 0 bytes in 0 blocks.
==27983==      possibly lost: 0 bytes in 0 blocks.
==27983==    still reachable: 276 bytes in 6 blocks.
==27983==         suppressed: 0 bytes in 0 blocks.

Signed-off-by: Yasushi SHOJI <[email-masked]>

---
diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -767,10 +767,16 @@ struct diff_filepair *diff_queue(struct 
 	return dp;
 }
 
+void diff_free_filespec(struct diff_filespec *s)
+{
+	diff_free_filespec_data(s);
+        free(s);
+}
+
 void diff_free_filepair(struct diff_filepair *p)
 {
-	diff_free_filespec_data(p->one);
-	diff_free_filespec_data(p->two);
+	diff_free_filespec(p->one);
+	diff_free_filespec(p->two);
 	free(p);
 }