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>
This commit is contained in:
Martin Ågren
2017-09-23 01:34:52 +02:00
committed by Junio C Hamano
parent b2ccdf7fc1
commit dcb572ab94
4 changed files with 6 additions and 7 deletions

View File

@ -182,8 +182,8 @@ static int commit_is_complete(struct commit *commit)
found.objects[i].item->flags |= SEEN; found.objects[i].item->flags |= SEEN;
} }
/* free object arrays */ /* free object arrays */
free(study.objects); object_array_clear(&study);
free(found.objects); object_array_clear(&found);
return !is_incomplete; return !is_incomplete;
} }

View File

@ -549,7 +549,6 @@ int index_differs_from(const char *def, int diff_flags,
rev.diffopt.flags |= diff_flags; rev.diffopt.flags |= diff_flags;
rev.diffopt.ita_invisible_in_index = ita_invisible_in_index; rev.diffopt.ita_invisible_in_index = ita_invisible_in_index;
run_diff_index(&rev, 1); run_diff_index(&rev, 1);
if (rev.pending.alloc) object_array_clear(&rev.pending);
free(rev.pending.objects);
return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0); return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0);
} }

View File

@ -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); add_object_array(merges.objects[i].item, NULL, result);
} }
free(merges.objects); object_array_clear(&merges);
return result->nr; 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); print_commit((struct commit *) merges.objects[i].item);
} }
free(merges.objects); object_array_clear(&merges);
return 0; return 0;
} }

View File

@ -888,7 +888,7 @@ static void receive_needs(void)
} }
shallow_nr += shallows.nr; shallow_nr += shallows.nr;
free(shallows.objects); object_array_clear(&shallows);
} }
/* return non-zero if the ref is hidden, otherwise 0 */ /* return non-zero if the ref is hidden, otherwise 0 */