object_array: use `object_array_clear()`, not `free()`

Instead of freeing `foo.objects` for an object array `foo` (sometimes conditionally), call `object_array_clear(&foo)`. This means we don't poke as much into the implementation, which is already a good thing, but also that we release the individual entries as well, thereby fixing at least one memory-leak (in diff-lib.c). If someone is holding on to a pointer to an element's `name` or `path`, that is now a dangling pointer, i.e., we'd be turning an unpleasant situation into an outright bug. To the best of my understanding no such long-term pointers are being taken. The way we handle `study` in builting/reflog.c still looks like it might leak. That will be addressed in the next commit. Signed-off-by: Martin Ågren <martin.agren@gmail.com> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Martin Ågren committed Sep 23, 2017 at 01:34 UTC dcb572ab94f83a1a857d276fcebff5700077f2b7
4 files changed +6 -7
builtin/reflog.c
+2 -2
@@ -182,8 +182,8 @@ static int commit_is_complete(struct commit *commit)
182 found.objects[i].item->flags |= SEEN;
183 }
184 /* free object arrays */
185 - free(study.objects);
186 - free(found.objects);
185 + object_array_clear(&study);
186 + object_array_clear(&found);
187 return !is_incomplete;
188 }
189
diff-lib.c
+1 -2
@@ -549,7 +549,6 @@ int index_differs_from(const char *def, int diff_flags,
549 rev.diffopt.flags |= diff_flags;
550 rev.diffopt.ita_invisible_in_index = ita_invisible_in_index;
551 run_diff_index(&rev, 1);
552 - if (rev.pending.alloc)
553 - free(rev.pending.objects);
552 + object_array_clear(&rev.pending);
553 return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0);
554 }
submodule.c
+2 -2
@@ -1728,7 +1728,7 @@ static int find_first_merges(struct object_array *result, const char *path,
1728 add_object_array(merges.objects[i].item, NULL, result);
1729 }
1730
1731 - free(merges.objects);
1731 + object_array_clear(&merges);
1732 return result->nr;
1733 }
1734
@@ -1833,7 +1833,7 @@ int merge_submodule(struct object_id *result, const char *path,
1833 print_commit((struct commit *) merges.objects[i].item);
1834 }
1835
1836 - free(merges.objects);
1836 + object_array_clear(&merges);
1837 return 0;
1838 }
1839
upload-pack.c
+1 -1
@@ -888,7 +888,7 @@ static void receive_needs(void)
888 }
889
890 shallow_nr += shallows.nr;
891 - free(shallows.objects);
891 + object_array_clear(&shallows);
892 }
893
894 /* return non-zero if the ref is hidden, otherwise 0 */