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@xxxxxxxxx> --- builtin/reflog.c | 4 ++-- diff-lib.c | 3 +-- submodule.c | 4 ++-- upload-pack.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/builtin/reflog.c b/builtin/reflog.c index e237d927a..6b34f23e7 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -182,8 +182,8 @@ static int commit_is_complete(struct commit *commit) found.objects[i].item->flags |= SEEN; } /* free object arrays */ - free(study.objects); - free(found.objects); + object_array_clear(&study); + object_array_clear(&found); return !is_incomplete; } diff --git a/diff-lib.c b/diff-lib.c index 2a52b0795..4e0980caa 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -549,7 +549,6 @@ int index_differs_from(const char *def, int diff_flags, rev.diffopt.flags |= diff_flags; rev.diffopt.ita_invisible_in_index = ita_invisible_in_index; run_diff_index(&rev, 1); - if (rev.pending.alloc) - free(rev.pending.objects); + object_array_clear(&rev.pending); return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0); } diff --git a/submodule.c b/submodule.c index 36f45f5a5..79fd01f7b 100644 --- a/submodule.c +++ b/submodule.c @@ -1728,7 +1728,7 @@ static int find_first_merges(struct object_array *result, const char *path, add_object_array(merges.objects[i].item, NULL, result); } - free(merges.objects); + object_array_clear(&merges); return result->nr; } @@ -1833,7 +1833,7 @@ int merge_submodule(struct object_id *result, const char *path, print_commit((struct commit *) merges.objects[i].item); } - free(merges.objects); + object_array_clear(&merges); return 0; } diff --git a/upload-pack.c b/upload-pack.c index 7efff2fbf..ec0eee8fc 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -888,7 +888,7 @@ static void receive_needs(void) } shallow_nr += shallows.nr; - free(shallows.objects); + object_array_clear(&shallows); } /* return non-zero if the ref is hidden, otherwise 0 */ -- 2.14.1.727.g9ddaf86