{"thread":{"id":"37563","subject":"[PATCH 1/2] add macro REALLOCARRAY","startedAt":"2014-09-14T16:55:56Z","lastAt":"2014-09-24T19:27:25Z","messageCount":14,"participants":["René Scharfe","Junio C Hamano","Jeff King","Michael Haggerty","Jonathan Nieder"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"249400","messageId":"5415C89C.4090509@web.de","threadId":"37563","inReplyTo":null,"subject":"[PATCH 1/2] add macro REALLOCARRAY","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-14T16:55:56Z","receivedAt":"2014-09-14T16:55:56Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"The macro ALLOC_GROW manages several aspects of dynamic memory\nallocations for arrays: It performs overprovisioning in order to avoid\nreallocations in future calls, updates the allocation size variable,\nmultiplies the item size and thus allows users to simply specify the\nitem count, performs the reallocation and updates the array pointer.\n\nSometimes this is too much.  Add the macro REALLOCARRAY, which only\ntakes care of the latter three points and allows users to specify the\nnumber of items an array can store directly.  It can increase and\nalso decrease its size.  Using this macro avoids duplicating the\narray pointer name and takes care of item sizes automatically.\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n Documentation/technical/api-allocation-growing.txt | 3 +++\n git-compat-util.h                                  | 2 ++\n 2 files changed, 5 insertions(+)\n\ndiff --git a/Documentation/technical/api-allocation-growing.txt b/Documentation/technical/api-allocation-growing.txt\nindex 542946b..4b5f049 100644\n--- a/Documentation/technical/api-allocation-growing.txt\n+++ b/Documentation/technical/api-allocation-growing.txt\n@@ -34,3 +34,6 @@ item[nr++] = value you like;\n ------------\n \n You are responsible for updating the `nr` variable.\n+\n+If you need to specify the number of elements to allocate explicitly\n+then use the macro `REALLOCARRAY(item, alloc)` instead of `ALLOC_GROW`.\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 4e7e3f8..d926e4c 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -626,6 +626,8 @@ extern int odb_mkstemp(char *template, size_t limit, const char *pattern);\n extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);\n extern char *xgetcwd(void);\n \n+#define REALLOCARRAY(x, alloc) x = xrealloc((x), (alloc) * sizeof(*(x)))\n+\n static inline size_t xsize_t(off_t len)\n {\n \tif (len > (size_t) len)\n-- \n2.1.0\n"},{"id":"249401","messageId":"5415C905.7000804@web.de","threadId":"37563","inReplyTo":"5415C89C.4090509@web.de","subject":"[PATCH 2/2] use REALLOCARRAY for changing the allocation size of arrays","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-14T16:57:41Z","receivedAt":"2014-09-14T16:57:41Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Signed-off-by: Rene Scharfe <l.s.r@web.de>\n---\n attr.c                 |  3 +--\n builtin/apply.c        |  2 +-\n builtin/for-each-ref.c |  9 +++------\n builtin/index-pack.c   |  4 +---\n builtin/log.c          |  2 +-\n builtin/merge.c        |  2 +-\n builtin/mv.c           |  8 ++++----\n builtin/pack-objects.c |  3 +--\n builtin/show-branch.c  |  2 +-\n cache.h                |  2 +-\n column.c               |  6 ++----\n commit-slab.h          |  3 +--\n fast-import.c          |  2 +-\n git.c                  |  3 +--\n graph.c                | 14 ++++----------\n khash.h                | 12 ++++--------\n line-log.c             |  2 +-\n object.c               |  2 +-\n pack-bitmap-write.c    |  3 +--\n pack-bitmap.c          |  6 ++----\n pack-objects.c         |  3 +--\n revision.c             |  2 +-\n sh-i18n--envsubst.c    |  5 +----\n shallow.c              |  3 +--\n string-list.c          |  3 +--\n walker.c               |  4 ++--\n 26 files changed, 40 insertions(+), 70 deletions(-)\n\ndiff --git a/attr.c b/attr.c\nindex 734222d..e89be50 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -97,8 +97,7 @@ static struct git_attr *git_attr_internal(const char *name, int len)\n \ta->attr_nr = attr_nr++;\n \tgit_attr_hash[pos] = a;\n \n-\tcheck_all_attr = xrealloc(check_all_attr,\n-\t\t\t\t  sizeof(*check_all_attr) * attr_nr);\n+\tREALLOCARRAY(check_all_attr, attr_nr);\n \tcheck_all_attr[a->attr_nr].attr = a;\n \tcheck_all_attr[a->attr_nr].value = ATTR__UNKNOWN;\n \treturn a;\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex f204cca..ae6ac6b 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2626,7 +2626,7 @@ static void update_image(struct image *img,\n \t\t * NOTE: this knows that we never call remove_first_line()\n \t\t * on anything other than pre/post image.\n \t\t */\n-\t\timg->line = xrealloc(img->line, nr * sizeof(*img->line));\n+\t\tREALLOCARRAY(img->line, nr);\n \t\timg->line_allocated = img->line;\n \t}\n \tif (preimage_limit != postimage->nr)\ndiff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c\nindex 47bd624..c5a06f3 100644\n--- a/builtin/for-each-ref.c\n+++ b/builtin/for-each-ref.c\n@@ -138,10 +138,8 @@ static int parse_atom(const char *atom, const char *ep)\n \t/* Add it in, including the deref prefix */\n \tat = used_atom_cnt;\n \tused_atom_cnt++;\n-\tused_atom = xrealloc(used_atom,\n-\t\t\t     (sizeof *used_atom) * used_atom_cnt);\n-\tused_atom_type = xrealloc(used_atom_type,\n-\t\t\t\t  (sizeof(*used_atom_type) * used_atom_cnt));\n+\tREALLOCARRAY(used_atom, used_atom_cnt);\n+\tREALLOCARRAY(used_atom_type, used_atom_cnt);\n \tused_atom[at] = xmemdupz(atom, ep - atom);\n \tused_atom_type[at] = valid_atom[i].cmp_type;\n \tif (*atom == '*')\n@@ -870,8 +868,7 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f\n \tref->flag = flag;\n \n \tcnt = cb->grab_cnt;\n-\tcb->grab_array = xrealloc(cb->grab_array,\n-\t\t\t\t  sizeof(*cb->grab_array) * (cnt + 1));\n+\tREALLOCARRAY(cb->grab_array, cnt + 1);\n \tcb->grab_array[cnt++] = ref;\n \tcb->grab_cnt = cnt;\n \treturn 0;\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex 5568a5b..5d03e00 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1140,9 +1140,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha\n \t\tint nr_objects_initial = nr_objects;\n \t\tif (nr_unresolved <= 0)\n \t\t\tdie(_(\"confusion beyond insanity\"));\n-\t\tobjects = xrealloc(objects,\n-\t\t\t\t   (nr_objects + nr_unresolved + 1)\n-\t\t\t\t   * sizeof(*objects));\n+\t\tREALLOCARRAY(objects, nr_objects + nr_unresolved + 1);\n \t\tmemset(objects + nr_objects + 1, 0,\n \t\t       nr_unresolved * sizeof(*objects));\n \t\tf = sha1fd(output_fd, curr_pack);\ndiff --git a/builtin/log.c b/builtin/log.c\nindex e4d8122..3852a63 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1440,7 +1440,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \n \t\tnr++;\n-\t\tlist = xrealloc(list, nr * sizeof(list[0]));\n+\t\tREALLOCARRAY(list, nr);\n \t\tlist[nr - 1] = commit;\n \t}\n \tif (nr == 0)\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 9da9e30..92e376f 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -556,7 +556,7 @@ static void parse_branch_merge_options(char *bmo)\n \tif (argc < 0)\n \t\tdie(_(\"Bad branch.%s.mergeoptions string: %s\"), branch,\n \t\t    split_cmdline_strerror(argc));\n-\targv = xrealloc(argv, sizeof(*argv) * (argc + 2));\n+\tREALLOCARRAY(argv, argc + 2);\n \tmemmove(argv + 1, argv, sizeof(*argv) * (argc + 1));\n \targc++;\n \targv[0] = \"branch.*.mergeoptions\";\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex bf784cb..236554d 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -184,10 +184,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \n \t\t\t\tmodes[i] = WORKING_DIRECTORY;\n \t\t\t\tn = argc + last - first;\n-\t\t\t\tsource = xrealloc(source, n * sizeof(char *));\n-\t\t\t\tdestination = xrealloc(destination, n * sizeof(char *));\n-\t\t\t\tmodes = xrealloc(modes, n * sizeof(enum update_mode));\n-\t\t\t\tsubmodule_gitfile = xrealloc(submodule_gitfile, n * sizeof(char *));\n+\t\t\t\tREALLOCARRAY(source, n);\n+\t\t\t\tREALLOCARRAY(destination, n);\n+\t\t\t\tREALLOCARRAY(modes, n);\n+\t\t\t\tREALLOCARRAY(submodule_gitfile, n);\n \n \t\t\t\tdst = add_slash(dst);\n \t\t\t\tdst_len = strlen(dst);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex b59f5d8..a6661b4 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -89,8 +89,7 @@ static void index_commit_for_bitmap(struct commit *commit)\n {\n \tif (indexed_commits_nr >= indexed_commits_alloc) {\n \t\tindexed_commits_alloc = (indexed_commits_alloc + 32) * 2;\n-\t\tindexed_commits = xrealloc(indexed_commits,\n-\t\t\tindexed_commits_alloc * sizeof(struct commit *));\n+\t\tREALLOCARRAY(indexed_commits, indexed_commits_alloc);\n \t}\n \n \tindexed_commits[indexed_commits_nr++] = commit;\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex 298c95e..9d465a8 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -563,7 +563,7 @@ static int git_show_branch_config(const char *var, const char *value, void *cb)\n \t\t\tdefault_arg[default_num++] = \"show-branch\";\n \t\t} else if (default_alloc <= default_num + 1) {\n \t\t\tdefault_alloc = default_alloc * 3 / 2 + 20;\n-\t\t\tdefault_arg = xrealloc(default_arg, sizeof *default_arg * default_alloc);\n+\t\t\tREALLOCARRAY(default_arg, default_alloc);\n \t\t}\n \t\tdefault_arg[default_num++] = xstrdup(value);\n \t\tdefault_arg[default_num] = NULL;\ndiff --git a/cache.h b/cache.h\nindex dfa1a56..fec45d0 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -482,7 +482,7 @@ extern int daemonize(void);\n \t\t\t\talloc = (nr); \\\n \t\t\telse \\\n \t\t\t\talloc = alloc_nr(alloc); \\\n-\t\t\tx = xrealloc((x), alloc * sizeof(*(x))); \\\n+\t\t\tREALLOCARRAY(x, alloc); \\\n \t\t} \\\n \t} while (0)\n \ndiff --git a/column.c b/column.c\nindex 76b615d..7459304 100644\n--- a/column.c\n+++ b/column.c\n@@ -81,8 +81,7 @@ static void compute_column_width(struct column_data *data)\n  */\n static void shrink_columns(struct column_data *data)\n {\n-\tdata->width = xrealloc(data->width,\n-\t\t\t       sizeof(*data->width) * data->cols);\n+\tREALLOCARRAY(data->width, data->cols);\n \twhile (data->rows > 1) {\n \t\tint x, total_width, cols, rows;\n \t\trows = data->rows;\n@@ -91,8 +90,7 @@ static void shrink_columns(struct column_data *data)\n \t\tdata->rows--;\n \t\tdata->cols = DIV_ROUND_UP(data->list->nr, data->rows);\n \t\tif (data->cols != cols)\n-\t\t\tdata->width = xrealloc(data->width,\n-\t\t\t\t\t       sizeof(*data->width) * data->cols);\n+\t\t\tREALLOCARRAY(data->width, data->cols);\n \t\tcompute_column_width(data);\n \n \t\ttotal_width = strlen(data->opts.indent);\ndiff --git a/commit-slab.h b/commit-slab.h\nindex 375c9c7..c94846c 100644\n--- a/commit-slab.h\n+++ b/commit-slab.h\n@@ -90,8 +90,7 @@ static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,\t\\\n \t\t\t\t\t\t\t\t\t\\\n \tif (s->slab_count <= nth_slab) {\t\t\t\t\\\n \t\tint i;\t\t\t\t\t\t\t\\\n-\t\ts->slab = xrealloc(s->slab,\t\t\t\t\\\n-\t\t\t\t   (nth_slab + 1) * sizeof(*s->slab));\t\\\n+\t\tREALLOCARRAY(s->slab, nth_slab + 1);\t\t\t\\\n \t\tstat_ ##slabname## realloc++;\t\t\t\t\\\n \t\tfor (i = s->slab_count; i <= nth_slab; i++)\t\t\\\n \t\t\ts->slab[i] = NULL;\t\t\t\t\\\ndiff --git a/fast-import.c b/fast-import.c\nindex c071253..d788e8f 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -878,7 +878,7 @@ static void start_packfile(void)\n \tpack_size = sizeof(hdr);\n \tobject_count = 0;\n \n-\tall_packs = xrealloc(all_packs, sizeof(*all_packs) * (pack_id + 1));\n+\tREALLOCARRAY(all_packs, pack_id + 1);\n \tall_packs[pack_id] = p;\n }\n \ndiff --git a/git.c b/git.c\nindex 210f1ae..7587b3a 100644\n--- a/git.c\n+++ b/git.c\n@@ -282,8 +282,7 @@ static int handle_alias(int *argcp, const char ***argv)\n \t\t\t\t  \"trace: alias expansion: %s =>\",\n \t\t\t\t  alias_command);\n \n-\t\tnew_argv = xrealloc(new_argv, sizeof(char *) *\n-\t\t\t\t    (count + *argcp));\n+\t\tREALLOCARRAY(new_argv, count + *argcp);\n \t\t/* insert after command name */\n \t\tmemcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp);\n \ndiff --git a/graph.c b/graph.c\nindex 6404331..494cf3e 100644\n--- a/graph.c\n+++ b/graph.c\n@@ -267,16 +267,10 @@ static void graph_ensure_capacity(struct git_graph *graph, int num_columns)\n \t\tgraph->column_capacity *= 2;\n \t} while (graph->column_capacity < num_columns);\n \n-\tgraph->columns = xrealloc(graph->columns,\n-\t\t\t\t  sizeof(struct column) *\n-\t\t\t\t  graph->column_capacity);\n-\tgraph->new_columns = xrealloc(graph->new_columns,\n-\t\t\t\t      sizeof(struct column) *\n-\t\t\t\t      graph->column_capacity);\n-\tgraph->mapping = xrealloc(graph->mapping,\n-\t\t\t\t  sizeof(int) * 2 * graph->column_capacity);\n-\tgraph->new_mapping = xrealloc(graph->new_mapping,\n-\t\t\t\t      sizeof(int) * 2 * graph->column_capacity);\n+\tREALLOCARRAY(graph->columns, graph->column_capacity);\n+\tREALLOCARRAY(graph->new_columns, graph->column_capacity);\n+\tREALLOCARRAY(graph->mapping, graph->column_capacity * 2);\n+\tREALLOCARRAY(graph->new_mapping, graph->column_capacity * 2);\n }\n \n /*\ndiff --git a/khash.h b/khash.h\nindex 06c7906..a5c56ed 100644\n--- a/khash.h\n+++ b/khash.h\n@@ -121,13 +121,9 @@ static const double __ac_HASH_UPPER = 0.77;\n \t\t\t\tif (!new_flags) return -1;\t\t\t\t\t\t\t\t\\\n \t\t\t\tmemset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \\\n \t\t\t\tif (h->n_buckets < new_n_buckets) {\t/* expand */\t\t\\\n-\t\t\t\t\tkhkey_t *new_keys = (khkey_t*)xrealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \\\n-\t\t\t\t\tif (!new_keys) return -1;\t\t\t\t\t\t\t\\\n-\t\t\t\t\th->keys = new_keys;\t\t\t\t\t\t\t\t\t\\\n+\t\t\t\t\tREALLOCARRAY(h->keys, new_n_buckets); \\\n \t\t\t\t\tif (kh_is_map) {\t\t\t\t\t\t\t\t\t\\\n-\t\t\t\t\t\tkhval_t *new_vals = (khval_t*)xrealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \\\n-\t\t\t\t\t\tif (!new_vals) return -1;\t\t\t\t\t\t\\\n-\t\t\t\t\t\th->vals = new_vals;\t\t\t\t\t\t\t\t\\\n+\t\t\t\t\t\tREALLOCARRAY(h->vals, new_n_buckets); \\\n \t\t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\t\t} /* otherwise shrink */\t\t\t\t\t\t\t\t\\\n \t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n@@ -160,8 +156,8 @@ static const double __ac_HASH_UPPER = 0.77;\n \t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\tif (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \\\n-\t\t\t\th->keys = (khkey_t*)xrealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \\\n-\t\t\t\tif (kh_is_map) h->vals = (khval_t*)xrealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \\\n+\t\t\t\tREALLOCARRAY(h->keys, new_n_buckets); \\\n+\t\t\t\tif (kh_is_map) REALLOCARRAY(h->vals, new_n_buckets); \\\n \t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\tfree(h->flags); /* free the working space */\t\t\t\t\\\n \t\t\th->flags = new_flags;\t\t\t\t\t\t\t\t\t\t\\\ndiff --git a/line-log.c b/line-log.c\nindex 1008e72..5eed873 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -533,7 +533,7 @@ static void fill_line_ends(struct diff_filespec *spec, long *lines,\n \t}\n \n \t/* shrink the array to fit the elements */\n-\tends = xrealloc(ends, cur * sizeof(*ends));\n+\tREALLOCARRAY(ends, cur);\n \t*lines = cur-1;\n \t*line_ends = ends;\n }\ndiff --git a/object.c b/object.c\nindex a16b9f9..000d315 100644\n--- a/object.c\n+++ b/object.c\n@@ -312,7 +312,7 @@ static void add_object_array_with_mode_context(struct object *obj, const char *n\n \n \tif (nr >= alloc) {\n \t\talloc = (alloc + 32) * 2;\n-\t\tobjects = xrealloc(objects, alloc * sizeof(*objects));\n+\t\tREALLOCARRAY(objects, alloc);\n \t\tarray->alloc = alloc;\n \t\tarray->objects = objects;\n \t}\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 5f1791a..7a01f6d 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -111,8 +111,7 @@ static inline void push_bitmapped_commit(struct commit *commit, struct ewah_bitm\n {\n \tif (writer.selected_nr >= writer.selected_alloc) {\n \t\twriter.selected_alloc = (writer.selected_alloc + 32) * 2;\n-\t\twriter.selected = xrealloc(writer.selected,\n-\t\t\t\t\t   writer.selected_alloc * sizeof(struct bitmapped_commit));\n+\t\tREALLOCARRAY(writer.selected, writer.selected_alloc);\n \t}\n \n \twriter.selected[writer.selected_nr].commit = commit;\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 91e4101..aa36317 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -400,10 +400,8 @@ static int ext_index_add_object(struct object *object, const char *name)\n \tif (hash_ret > 0) {\n \t\tif (eindex->count >= eindex->alloc) {\n \t\t\teindex->alloc = (eindex->alloc + 16) * 3 / 2;\n-\t\t\teindex->objects = xrealloc(eindex->objects,\n-\t\t\t\teindex->alloc * sizeof(struct object *));\n-\t\t\teindex->hashes = xrealloc(eindex->hashes,\n-\t\t\t\teindex->alloc * sizeof(uint32_t));\n+\t\t\tREALLOCARRAY(eindex->objects, eindex->alloc);\n+\t\t\tREALLOCARRAY(eindex->hashes, eindex->alloc);\n \t\t}\n \n \t\tbitmap_pos = eindex->count;\ndiff --git a/pack-objects.c b/pack-objects.c\nindex 9992f3e..076b434 100644\n--- a/pack-objects.c\n+++ b/pack-objects.c\n@@ -92,8 +92,7 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,\n \n \tif (pdata->nr_objects >= pdata->nr_alloc) {\n \t\tpdata->nr_alloc = (pdata->nr_alloc  + 1024) * 3 / 2;\n-\t\tpdata->objects = xrealloc(pdata->objects,\n-\t\t\t\t\t  pdata->nr_alloc * sizeof(*new_entry));\n+\t\tREALLOCARRAY(pdata->objects, pdata->nr_alloc);\n \t}\n \n \tnew_entry = pdata->objects + pdata->nr_objects++;\ndiff --git a/revision.c b/revision.c\nindex 0d3e417..eaa3f74 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1397,7 +1397,7 @@ static void prepare_show_merge(struct rev_info *revs)\n \t\t\tcontinue;\n \t\tif (ce_path_match(ce, &revs->prune_data, NULL)) {\n \t\t\tprune_num++;\n-\t\t\tprune = xrealloc(prune, sizeof(*prune) * prune_num);\n+\t\t\tREALLOCARRAY(prune, prune_num);\n \t\t\tprune[prune_num-2] = ce->name;\n \t\t\tprune[prune_num-1] = NULL;\n \t\t}\ndiff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c\nindex 6dd03a9..55d2a8b 100644\n--- a/sh-i18n--envsubst.c\n+++ b/sh-i18n--envsubst.c\n@@ -208,11 +208,8 @@ string_list_append (string_list_ty *slp, const char *s)\n   /* Grow the list.  */\n   if (slp->nitems >= slp->nitems_max)\n     {\n-      size_t nbytes;\n-\n       slp->nitems_max = slp->nitems_max * 2 + 4;\n-      nbytes = slp->nitems_max * sizeof (slp->item[0]);\n-      slp->item = (const char **) xrealloc (slp->item, nbytes);\n+      REALLOCARRAY(slp->item, slp->nitems_max);\n     }\n \n   /* Add the string to the end of the list.  */\ndiff --git a/shallow.c b/shallow.c\nindex de07709..f25109a 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -392,8 +392,7 @@ static uint32_t *paint_alloc(struct paint_info *info)\n \tvoid *p;\n \tif (!info->slab_count || info->free + size > info->end) {\n \t\tinfo->slab_count++;\n-\t\tinfo->slab = xrealloc(info->slab,\n-\t\t\t\t      info->slab_count * sizeof(*info->slab));\n+\t\tREALLOCARRAY(info->slab, info->slab_count);\n \t\tinfo->free = xmalloc(COMMIT_SLAB_SIZE);\n \t\tinfo->slab[info->slab_count - 1] = info->free;\n \t\tinfo->end = info->free + COMMIT_SLAB_SIZE;\ndiff --git a/string-list.c b/string-list.c\nindex db38b62..9050d38 100644\n--- a/string-list.c\n+++ b/string-list.c\n@@ -43,8 +43,7 @@ static int add_entry(int insert_at, struct string_list *list, const char *string\n \n \tif (list->nr + 1 >= list->alloc) {\n \t\tlist->alloc += 32;\n-\t\tlist->items = xrealloc(list->items, list->alloc\n-\t\t\t\t* sizeof(struct string_list_item));\n+\t\tREALLOCARRAY(list->items, list->alloc);\n \t}\n \tif (index < list->nr)\n \t\tmemmove(list->items + index + 1, list->items + index,\ndiff --git a/walker.c b/walker.c\nindex f8d3709..169f5cb 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -228,8 +228,8 @@ int walker_targets_stdin(char ***target, const char ***write_ref)\n \n \t\tif (targets >= targets_alloc) {\n \t\t\ttargets_alloc = targets_alloc ? targets_alloc * 2 : 64;\n-\t\t\t*target = xrealloc(*target, targets_alloc * sizeof(**target));\n-\t\t\t*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));\n+\t\t\tREALLOCARRAY(*target, targets_alloc);\n+\t\t\tREALLOCARRAY(*write_ref, targets_alloc);\n \t\t}\n \t\t(*target)[targets] = xstrdup(tg_one);\n \t\t(*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;\n-- \n2.1.0\n"},{"id":"249442","messageId":"xmqqtx487nej.fsf@gitster.dls.corp.google.com","threadId":"37563","inReplyTo":"5415C89C.4090509@web.de","subject":"Re: [PATCH 1/2] add macro REALLOCARRAY","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-09-15T18:24:04Z","receivedAt":"2014-09-15T18:24:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> The macro ALLOC_GROW manages several aspects of dynamic memory\n> allocations for arrays: It performs overprovisioning in order to avoid\n> reallocations in future calls, updates the allocation size variable,\n> multiplies the item size and thus allows users to simply specify the\n> item count, performs the reallocation and updates the array pointer.\n>\n> Sometimes this is too much.  Add the macro REALLOCARRAY, which only\n> takes care of the latter three points and allows users to specify the\n> number of items an array can store directly.  It can increase and\n> also decrease its size.  Using this macro avoids duplicating the\n> array pointer name and takes care of item sizes automatically.\n>\n> Signed-off-by: Rene Scharfe <l.s.r@web.de>\n> ---\n\nMakes sense.  Originally I had two minor gripes against this\n\n #1 a macro that modifies its arguments feels a bit too magical, and\n    we would not want to overuse them.\n\n #2 REALLOC_ARRAY(array, size) would have been easier to read.\n\nBut #1 is shared with ALLOC_GROW(), and as long as we use it\neverywhere (and by the looks of 2/2 we fairly widely do), readers\nwill get used to the pattern.  #2 still stands, though.\n\nThanks.\n\n>  Documentation/technical/api-allocation-growing.txt | 3 +++\n>  git-compat-util.h                                  | 2 ++\n>  2 files changed, 5 insertions(+)\n>\n> diff --git a/Documentation/technical/api-allocation-growing.txt b/Documentation/technical/api-allocation-growing.txt\n> index 542946b..4b5f049 100644\n> --- a/Documentation/technical/api-allocation-growing.txt\n> +++ b/Documentation/technical/api-allocation-growing.txt\n> @@ -34,3 +34,6 @@ item[nr++] = value you like;\n>  ------------\n>  \n>  You are responsible for updating the `nr` variable.\n> +\n> +If you need to specify the number of elements to allocate explicitly\n> +then use the macro `REALLOCARRAY(item, alloc)` instead of `ALLOC_GROW`.\n> diff --git a/git-compat-util.h b/git-compat-util.h\n> index 4e7e3f8..d926e4c 100644\n> --- a/git-compat-util.h\n> +++ b/git-compat-util.h\n> @@ -626,6 +626,8 @@ extern int odb_mkstemp(char *template, size_t limit, const char *pattern);\n>  extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);\n>  extern char *xgetcwd(void);\n>  \n> +#define REALLOCARRAY(x, alloc) x = xrealloc((x), (alloc) * sizeof(*(x)))\n> +\n>  static inline size_t xsize_t(off_t len)\n>  {\n>  \tif (len > (size_t) len)\n"},{"id":"249500","messageId":"CAPc5daXuYVXG=b3Mjn=8oE71FqE_PRZ=XHXW_0F5uHawWwy4HQ@mail.gmail.com","threadId":"37563","inReplyTo":"5415C89C.4090509@web.de","subject":"Re: [PATCH 1/2] add macro REALLOCARRAY","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-09-16T03:04:37Z","receivedAt":"2014-09-16T03:04:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"On Sun, Sep 14, 2014 at 9:55 AM, René Scharfe <l.s.r@web.de> wrote:\n> +#define REALLOCARRAY(x, alloc) x = xrealloc((x), (alloc) * sizeof(*(x)))\n\nI have been wondering if \"x\" could be an expression that has an operator\nthat binds weaker than the assignment '='.  That may necessitate the LHS\nof the assignment to be somehow marked as bound the tightest, i.e.\n\n#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))\n\nOr am I being overly silly?\n"},{"id":"249517","messageId":"541886D5.8060202@web.de","threadId":"37563","inReplyTo":"CAPc5daXuYVXG=b3Mjn=8oE71FqE_PRZ=XHXW_0F5uHawWwy4HQ@mail.gmail.com","subject":"Re: [PATCH 1/2] add macro REALLOCARRAY","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-16T18:52:05Z","receivedAt":"2014-09-16T18:52:05Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 16.09.2014 um 05:04 schrieb Junio C Hamano:\n> On Sun, Sep 14, 2014 at 9:55 AM, René Scharfe <l.s.r@web.de> wrote:\n>> +#define REALLOCARRAY(x, alloc) x = xrealloc((x), (alloc) * sizeof(*(x)))\n>\n> I have been wondering if \"x\" could be an expression that has an operator\n> that binds weaker than the assignment '='.  That may necessitate the LHS\n> of the assignment to be somehow marked as bound the tightest, i.e.\n>\n> #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))\n>\n> Or am I being overly silly?\n\nALLOC_GROW did well without that.  I can't think of a good use case for \na complex expression on the right-hand side.  That said, I think I still \nhave a spare matching pair of parentheses lying around here somewhere, \nso let's play it safe and use them. :)\n\nThe added underscore is a good idea as well.\n\nRené\n"},{"id":"249518","messageId":"541887F0.1050007@web.de","threadId":"37563","inReplyTo":"541886D5.8060202@web.de","subject":"[PATCH 1/2] add macro REALLOC_ARRAY","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-16T18:56:48Z","receivedAt":"2014-09-16T18:56:48Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"The macro ALLOC_GROW manages several aspects of dynamic memory\nallocations for arrays: It performs overprovisioning in order to avoid\nreallocations in future calls, updates the allocation size variable,\nmultiplies the item size and thus allows users to simply specify the\nitem count, performs the reallocation and updates the array pointer.\n\nSometimes this is too much.  Add the macro REALLOC_ARRAY, which only\ntakes care of the latter three points and allows users to specfiy the\nnumber of items the array can store.  It can increase and also decrease\nthe size.  Using the macro avoid duplicating the variable name and\ntakes care of the item sizes automatically.\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n Documentation/technical/api-allocation-growing.txt | 3 +++\n git-compat-util.h                                  | 2 ++\n 2 files changed, 5 insertions(+)\n\ndiff --git a/Documentation/technical/api-allocation-growing.txt b/Documentation/technical/api-allocation-growing.txt\nindex 542946b..5a59b54 100644\n--- a/Documentation/technical/api-allocation-growing.txt\n+++ b/Documentation/technical/api-allocation-growing.txt\n@@ -34,3 +34,6 @@ item[nr++] = value you like;\n ------------\n \n You are responsible for updating the `nr` variable.\n+\n+If you need to specify the number of elements to allocate explicitly\n+then use the macro `REALLOC_ARRAY(item, alloc)` instead of `ALLOC_GROW`.\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 4e7e3f8..5a15b53 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -626,6 +626,8 @@ extern int odb_mkstemp(char *template, size_t limit, const char *pattern);\n extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);\n extern char *xgetcwd(void);\n \n+#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))\n+\n static inline size_t xsize_t(off_t len)\n {\n \tif (len > (size_t) len)\n-- \n2.1.0\n"},{"id":"249519","messageId":"541887F9.3000100@web.de","threadId":"37563","inReplyTo":"541886D5.8060202@web.de","subject":"[PATCH 2/2] use REALLOC_ARRAY for changing the allocation size of arrays","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-16T18:56:57Z","receivedAt":"2014-09-16T18:56:57Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Signed-off-by: Rene Scharfe <l.s.r@web.de>\n---\n attr.c                 |  3 +--\n builtin/apply.c        |  2 +-\n builtin/for-each-ref.c |  9 +++------\n builtin/index-pack.c   |  4 +---\n builtin/log.c          |  2 +-\n builtin/merge.c        |  2 +-\n builtin/mv.c           |  8 ++++----\n builtin/pack-objects.c |  3 +--\n builtin/show-branch.c  |  2 +-\n cache.h                |  2 +-\n column.c               |  6 ++----\n commit-slab.h          |  3 +--\n fast-import.c          |  2 +-\n git.c                  |  3 +--\n graph.c                | 14 ++++----------\n khash.h                | 12 ++++--------\n line-log.c             |  2 +-\n object.c               |  2 +-\n pack-bitmap-write.c    |  3 +--\n pack-bitmap.c          |  6 ++----\n pack-objects.c         |  3 +--\n revision.c             |  2 +-\n sh-i18n--envsubst.c    |  5 +----\n shallow.c              |  3 +--\n string-list.c          |  3 +--\n walker.c               |  4 ++--\n 26 files changed, 40 insertions(+), 70 deletions(-)\n\ndiff --git a/attr.c b/attr.c\nindex 734222d..cd54697 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -97,8 +97,7 @@ static struct git_attr *git_attr_internal(const char *name, int len)\n \ta->attr_nr = attr_nr++;\n \tgit_attr_hash[pos] = a;\n \n-\tcheck_all_attr = xrealloc(check_all_attr,\n-\t\t\t\t  sizeof(*check_all_attr) * attr_nr);\n+\tREALLOC_ARRAY(check_all_attr, attr_nr);\n \tcheck_all_attr[a->attr_nr].attr = a;\n \tcheck_all_attr[a->attr_nr].value = ATTR__UNKNOWN;\n \treturn a;\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex f204cca..8714a88 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2626,7 +2626,7 @@ static void update_image(struct image *img,\n \t\t * NOTE: this knows that we never call remove_first_line()\n \t\t * on anything other than pre/post image.\n \t\t */\n-\t\timg->line = xrealloc(img->line, nr * sizeof(*img->line));\n+\t\tREALLOC_ARRAY(img->line, nr);\n \t\timg->line_allocated = img->line;\n \t}\n \tif (preimage_limit != postimage->nr)\ndiff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c\nindex 47bd624..7f55e68 100644\n--- a/builtin/for-each-ref.c\n+++ b/builtin/for-each-ref.c\n@@ -138,10 +138,8 @@ static int parse_atom(const char *atom, const char *ep)\n \t/* Add it in, including the deref prefix */\n \tat = used_atom_cnt;\n \tused_atom_cnt++;\n-\tused_atom = xrealloc(used_atom,\n-\t\t\t     (sizeof *used_atom) * used_atom_cnt);\n-\tused_atom_type = xrealloc(used_atom_type,\n-\t\t\t\t  (sizeof(*used_atom_type) * used_atom_cnt));\n+\tREALLOC_ARRAY(used_atom, used_atom_cnt);\n+\tREALLOC_ARRAY(used_atom_type, used_atom_cnt);\n \tused_atom[at] = xmemdupz(atom, ep - atom);\n \tused_atom_type[at] = valid_atom[i].cmp_type;\n \tif (*atom == '*')\n@@ -870,8 +868,7 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f\n \tref->flag = flag;\n \n \tcnt = cb->grab_cnt;\n-\tcb->grab_array = xrealloc(cb->grab_array,\n-\t\t\t\t  sizeof(*cb->grab_array) * (cnt + 1));\n+\tREALLOC_ARRAY(cb->grab_array, cnt + 1);\n \tcb->grab_array[cnt++] = ref;\n \tcb->grab_cnt = cnt;\n \treturn 0;\ndiff --git a/builtin/index-pack.c b/builtin/index-pack.c\nindex 5568a5b..783623d 100644\n--- a/builtin/index-pack.c\n+++ b/builtin/index-pack.c\n@@ -1140,9 +1140,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha\n \t\tint nr_objects_initial = nr_objects;\n \t\tif (nr_unresolved <= 0)\n \t\t\tdie(_(\"confusion beyond insanity\"));\n-\t\tobjects = xrealloc(objects,\n-\t\t\t\t   (nr_objects + nr_unresolved + 1)\n-\t\t\t\t   * sizeof(*objects));\n+\t\tREALLOC_ARRAY(objects, nr_objects + nr_unresolved + 1);\n \t\tmemset(objects + nr_objects + 1, 0,\n \t\t       nr_unresolved * sizeof(*objects));\n \t\tf = sha1fd(output_fd, curr_pack);\ndiff --git a/builtin/log.c b/builtin/log.c\nindex e4d8122..7643396 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -1440,7 +1440,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \n \t\tnr++;\n-\t\tlist = xrealloc(list, nr * sizeof(list[0]));\n+\t\tREALLOC_ARRAY(list, nr);\n \t\tlist[nr - 1] = commit;\n \t}\n \tif (nr == 0)\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 9da9e30..cb9af1e 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -556,7 +556,7 @@ static void parse_branch_merge_options(char *bmo)\n \tif (argc < 0)\n \t\tdie(_(\"Bad branch.%s.mergeoptions string: %s\"), branch,\n \t\t    split_cmdline_strerror(argc));\n-\targv = xrealloc(argv, sizeof(*argv) * (argc + 2));\n+\tREALLOC_ARRAY(argv, argc + 2);\n \tmemmove(argv + 1, argv, sizeof(*argv) * (argc + 1));\n \targc++;\n \targv[0] = \"branch.*.mergeoptions\";\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex bf784cb..8883baa 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -184,10 +184,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \n \t\t\t\tmodes[i] = WORKING_DIRECTORY;\n \t\t\t\tn = argc + last - first;\n-\t\t\t\tsource = xrealloc(source, n * sizeof(char *));\n-\t\t\t\tdestination = xrealloc(destination, n * sizeof(char *));\n-\t\t\t\tmodes = xrealloc(modes, n * sizeof(enum update_mode));\n-\t\t\t\tsubmodule_gitfile = xrealloc(submodule_gitfile, n * sizeof(char *));\n+\t\t\t\tREALLOC_ARRAY(source, n);\n+\t\t\t\tREALLOC_ARRAY(destination, n);\n+\t\t\t\tREALLOC_ARRAY(modes, n);\n+\t\t\t\tREALLOC_ARRAY(submodule_gitfile, n);\n \n \t\t\t\tdst = add_slash(dst);\n \t\t\t\tdst_len = strlen(dst);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex b59f5d8..d391934 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -89,8 +89,7 @@ static void index_commit_for_bitmap(struct commit *commit)\n {\n \tif (indexed_commits_nr >= indexed_commits_alloc) {\n \t\tindexed_commits_alloc = (indexed_commits_alloc + 32) * 2;\n-\t\tindexed_commits = xrealloc(indexed_commits,\n-\t\t\tindexed_commits_alloc * sizeof(struct commit *));\n+\t\tREALLOC_ARRAY(indexed_commits, indexed_commits_alloc);\n \t}\n \n \tindexed_commits[indexed_commits_nr++] = commit;\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex 298c95e..a127523 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -563,7 +563,7 @@ static int git_show_branch_config(const char *var, const char *value, void *cb)\n \t\t\tdefault_arg[default_num++] = \"show-branch\";\n \t\t} else if (default_alloc <= default_num + 1) {\n \t\t\tdefault_alloc = default_alloc * 3 / 2 + 20;\n-\t\t\tdefault_arg = xrealloc(default_arg, sizeof *default_arg * default_alloc);\n+\t\t\tREALLOC_ARRAY(default_arg, default_alloc);\n \t\t}\n \t\tdefault_arg[default_num++] = xstrdup(value);\n \t\tdefault_arg[default_num] = NULL;\ndiff --git a/cache.h b/cache.h\nindex dfa1a56..6cbef2c 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -482,7 +482,7 @@ extern int daemonize(void);\n \t\t\t\talloc = (nr); \\\n \t\t\telse \\\n \t\t\t\talloc = alloc_nr(alloc); \\\n-\t\t\tx = xrealloc((x), alloc * sizeof(*(x))); \\\n+\t\t\tREALLOC_ARRAY(x, alloc); \\\n \t\t} \\\n \t} while (0)\n \ndiff --git a/column.c b/column.c\nindex 76b615d..8082a94 100644\n--- a/column.c\n+++ b/column.c\n@@ -81,8 +81,7 @@ static void compute_column_width(struct column_data *data)\n  */\n static void shrink_columns(struct column_data *data)\n {\n-\tdata->width = xrealloc(data->width,\n-\t\t\t       sizeof(*data->width) * data->cols);\n+\tREALLOC_ARRAY(data->width, data->cols);\n \twhile (data->rows > 1) {\n \t\tint x, total_width, cols, rows;\n \t\trows = data->rows;\n@@ -91,8 +90,7 @@ static void shrink_columns(struct column_data *data)\n \t\tdata->rows--;\n \t\tdata->cols = DIV_ROUND_UP(data->list->nr, data->rows);\n \t\tif (data->cols != cols)\n-\t\t\tdata->width = xrealloc(data->width,\n-\t\t\t\t\t       sizeof(*data->width) * data->cols);\n+\t\t\tREALLOC_ARRAY(data->width, data->cols);\n \t\tcompute_column_width(data);\n \n \t\ttotal_width = strlen(data->opts.indent);\ndiff --git a/commit-slab.h b/commit-slab.h\nindex 375c9c7..f37ec38 100644\n--- a/commit-slab.h\n+++ b/commit-slab.h\n@@ -90,8 +90,7 @@ static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,\t\\\n \t\t\t\t\t\t\t\t\t\\\n \tif (s->slab_count <= nth_slab) {\t\t\t\t\\\n \t\tint i;\t\t\t\t\t\t\t\\\n-\t\ts->slab = xrealloc(s->slab,\t\t\t\t\\\n-\t\t\t\t   (nth_slab + 1) * sizeof(*s->slab));\t\\\n+\t\tREALLOC_ARRAY(s->slab, nth_slab + 1);\t\t\t\\\n \t\tstat_ ##slabname## realloc++;\t\t\t\t\\\n \t\tfor (i = s->slab_count; i <= nth_slab; i++)\t\t\\\n \t\t\ts->slab[i] = NULL;\t\t\t\t\\\ndiff --git a/fast-import.c b/fast-import.c\nindex c071253..07f65ec 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -878,7 +878,7 @@ static void start_packfile(void)\n \tpack_size = sizeof(hdr);\n \tobject_count = 0;\n \n-\tall_packs = xrealloc(all_packs, sizeof(*all_packs) * (pack_id + 1));\n+\tREALLOC_ARRAY(all_packs, pack_id + 1);\n \tall_packs[pack_id] = p;\n }\n \ndiff --git a/git.c b/git.c\nindex 210f1ae..d5bb674 100644\n--- a/git.c\n+++ b/git.c\n@@ -282,8 +282,7 @@ static int handle_alias(int *argcp, const char ***argv)\n \t\t\t\t  \"trace: alias expansion: %s =>\",\n \t\t\t\t  alias_command);\n \n-\t\tnew_argv = xrealloc(new_argv, sizeof(char *) *\n-\t\t\t\t    (count + *argcp));\n+\t\tREALLOC_ARRAY(new_argv, count + *argcp);\n \t\t/* insert after command name */\n \t\tmemcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp);\n \ndiff --git a/graph.c b/graph.c\nindex 6404331..288b9a6 100644\n--- a/graph.c\n+++ b/graph.c\n@@ -267,16 +267,10 @@ static void graph_ensure_capacity(struct git_graph *graph, int num_columns)\n \t\tgraph->column_capacity *= 2;\n \t} while (graph->column_capacity < num_columns);\n \n-\tgraph->columns = xrealloc(graph->columns,\n-\t\t\t\t  sizeof(struct column) *\n-\t\t\t\t  graph->column_capacity);\n-\tgraph->new_columns = xrealloc(graph->new_columns,\n-\t\t\t\t      sizeof(struct column) *\n-\t\t\t\t      graph->column_capacity);\n-\tgraph->mapping = xrealloc(graph->mapping,\n-\t\t\t\t  sizeof(int) * 2 * graph->column_capacity);\n-\tgraph->new_mapping = xrealloc(graph->new_mapping,\n-\t\t\t\t      sizeof(int) * 2 * graph->column_capacity);\n+\tREALLOC_ARRAY(graph->columns, graph->column_capacity);\n+\tREALLOC_ARRAY(graph->new_columns, graph->column_capacity);\n+\tREALLOC_ARRAY(graph->mapping, graph->column_capacity * 2);\n+\tREALLOC_ARRAY(graph->new_mapping, graph->column_capacity * 2);\n }\n \n /*\ndiff --git a/khash.h b/khash.h\nindex 06c7906..376475a 100644\n--- a/khash.h\n+++ b/khash.h\n@@ -121,13 +121,9 @@ static const double __ac_HASH_UPPER = 0.77;\n \t\t\t\tif (!new_flags) return -1;\t\t\t\t\t\t\t\t\\\n \t\t\t\tmemset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \\\n \t\t\t\tif (h->n_buckets < new_n_buckets) {\t/* expand */\t\t\\\n-\t\t\t\t\tkhkey_t *new_keys = (khkey_t*)xrealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \\\n-\t\t\t\t\tif (!new_keys) return -1;\t\t\t\t\t\t\t\\\n-\t\t\t\t\th->keys = new_keys;\t\t\t\t\t\t\t\t\t\\\n+\t\t\t\t\tREALLOC_ARRAY(h->keys, new_n_buckets); \\\n \t\t\t\t\tif (kh_is_map) {\t\t\t\t\t\t\t\t\t\\\n-\t\t\t\t\t\tkhval_t *new_vals = (khval_t*)xrealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \\\n-\t\t\t\t\t\tif (!new_vals) return -1;\t\t\t\t\t\t\\\n-\t\t\t\t\t\th->vals = new_vals;\t\t\t\t\t\t\t\t\\\n+\t\t\t\t\t\tREALLOC_ARRAY(h->vals, new_n_buckets); \\\n \t\t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\t\t} /* otherwise shrink */\t\t\t\t\t\t\t\t\\\n \t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n@@ -160,8 +156,8 @@ static const double __ac_HASH_UPPER = 0.77;\n \t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\tif (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \\\n-\t\t\t\th->keys = (khkey_t*)xrealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \\\n-\t\t\t\tif (kh_is_map) h->vals = (khval_t*)xrealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \\\n+\t\t\t\tREALLOC_ARRAY(h->keys, new_n_buckets); \\\n+\t\t\t\tif (kh_is_map) REALLOC_ARRAY(h->vals, new_n_buckets); \\\n \t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n \t\t\tfree(h->flags); /* free the working space */\t\t\t\t\\\n \t\t\th->flags = new_flags;\t\t\t\t\t\t\t\t\t\t\\\ndiff --git a/line-log.c b/line-log.c\nindex 1008e72..038c58a 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -533,7 +533,7 @@ static void fill_line_ends(struct diff_filespec *spec, long *lines,\n \t}\n \n \t/* shrink the array to fit the elements */\n-\tends = xrealloc(ends, cur * sizeof(*ends));\n+\tREALLOC_ARRAY(ends, cur);\n \t*lines = cur-1;\n \t*line_ends = ends;\n }\ndiff --git a/object.c b/object.c\nindex a16b9f9..4e36669 100644\n--- a/object.c\n+++ b/object.c\n@@ -312,7 +312,7 @@ static void add_object_array_with_mode_context(struct object *obj, const char *n\n \n \tif (nr >= alloc) {\n \t\talloc = (alloc + 32) * 2;\n-\t\tobjects = xrealloc(objects, alloc * sizeof(*objects));\n+\t\tREALLOC_ARRAY(objects, alloc);\n \t\tarray->alloc = alloc;\n \t\tarray->objects = objects;\n \t}\ndiff --git a/pack-bitmap-write.c b/pack-bitmap-write.c\nindex 5f1791a..8029ae3 100644\n--- a/pack-bitmap-write.c\n+++ b/pack-bitmap-write.c\n@@ -111,8 +111,7 @@ static inline void push_bitmapped_commit(struct commit *commit, struct ewah_bitm\n {\n \tif (writer.selected_nr >= writer.selected_alloc) {\n \t\twriter.selected_alloc = (writer.selected_alloc + 32) * 2;\n-\t\twriter.selected = xrealloc(writer.selected,\n-\t\t\t\t\t   writer.selected_alloc * sizeof(struct bitmapped_commit));\n+\t\tREALLOC_ARRAY(writer.selected, writer.selected_alloc);\n \t}\n \n \twriter.selected[writer.selected_nr].commit = commit;\ndiff --git a/pack-bitmap.c b/pack-bitmap.c\nindex 91e4101..a1f3c0d 100644\n--- a/pack-bitmap.c\n+++ b/pack-bitmap.c\n@@ -400,10 +400,8 @@ static int ext_index_add_object(struct object *object, const char *name)\n \tif (hash_ret > 0) {\n \t\tif (eindex->count >= eindex->alloc) {\n \t\t\teindex->alloc = (eindex->alloc + 16) * 3 / 2;\n-\t\t\teindex->objects = xrealloc(eindex->objects,\n-\t\t\t\teindex->alloc * sizeof(struct object *));\n-\t\t\teindex->hashes = xrealloc(eindex->hashes,\n-\t\t\t\teindex->alloc * sizeof(uint32_t));\n+\t\t\tREALLOC_ARRAY(eindex->objects, eindex->alloc);\n+\t\t\tREALLOC_ARRAY(eindex->hashes, eindex->alloc);\n \t\t}\n \n \t\tbitmap_pos = eindex->count;\ndiff --git a/pack-objects.c b/pack-objects.c\nindex 9992f3e..6398a8a 100644\n--- a/pack-objects.c\n+++ b/pack-objects.c\n@@ -92,8 +92,7 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,\n \n \tif (pdata->nr_objects >= pdata->nr_alloc) {\n \t\tpdata->nr_alloc = (pdata->nr_alloc  + 1024) * 3 / 2;\n-\t\tpdata->objects = xrealloc(pdata->objects,\n-\t\t\t\t\t  pdata->nr_alloc * sizeof(*new_entry));\n+\t\tREALLOC_ARRAY(pdata->objects, pdata->nr_alloc);\n \t}\n \n \tnew_entry = pdata->objects + pdata->nr_objects++;\ndiff --git a/revision.c b/revision.c\nindex 0d3e417..e498b7c 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1397,7 +1397,7 @@ static void prepare_show_merge(struct rev_info *revs)\n \t\t\tcontinue;\n \t\tif (ce_path_match(ce, &revs->prune_data, NULL)) {\n \t\t\tprune_num++;\n-\t\t\tprune = xrealloc(prune, sizeof(*prune) * prune_num);\n+\t\t\tREALLOC_ARRAY(prune, prune_num);\n \t\t\tprune[prune_num-2] = ce->name;\n \t\t\tprune[prune_num-1] = NULL;\n \t\t}\ndiff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c\nindex 6dd03a9..2842a22 100644\n--- a/sh-i18n--envsubst.c\n+++ b/sh-i18n--envsubst.c\n@@ -208,11 +208,8 @@ string_list_append (string_list_ty *slp, const char *s)\n   /* Grow the list.  */\n   if (slp->nitems >= slp->nitems_max)\n     {\n-      size_t nbytes;\n-\n       slp->nitems_max = slp->nitems_max * 2 + 4;\n-      nbytes = slp->nitems_max * sizeof (slp->item[0]);\n-      slp->item = (const char **) xrealloc (slp->item, nbytes);\n+      REALLOC_ARRAY(slp->item, slp->nitems_max);\n     }\n \n   /* Add the string to the end of the list.  */\ndiff --git a/shallow.c b/shallow.c\nindex de07709..57f4afa 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -392,8 +392,7 @@ static uint32_t *paint_alloc(struct paint_info *info)\n \tvoid *p;\n \tif (!info->slab_count || info->free + size > info->end) {\n \t\tinfo->slab_count++;\n-\t\tinfo->slab = xrealloc(info->slab,\n-\t\t\t\t      info->slab_count * sizeof(*info->slab));\n+\t\tREALLOC_ARRAY(info->slab, info->slab_count);\n \t\tinfo->free = xmalloc(COMMIT_SLAB_SIZE);\n \t\tinfo->slab[info->slab_count - 1] = info->free;\n \t\tinfo->end = info->free + COMMIT_SLAB_SIZE;\ndiff --git a/string-list.c b/string-list.c\nindex db38b62..c5aa076 100644\n--- a/string-list.c\n+++ b/string-list.c\n@@ -43,8 +43,7 @@ static int add_entry(int insert_at, struct string_list *list, const char *string\n \n \tif (list->nr + 1 >= list->alloc) {\n \t\tlist->alloc += 32;\n-\t\tlist->items = xrealloc(list->items, list->alloc\n-\t\t\t\t* sizeof(struct string_list_item));\n+\t\tREALLOC_ARRAY(list->items, list->alloc);\n \t}\n \tif (index < list->nr)\n \t\tmemmove(list->items + index + 1, list->items + index,\ndiff --git a/walker.c b/walker.c\nindex f8d3709..18a67d3 100644\n--- a/walker.c\n+++ b/walker.c\n@@ -228,8 +228,8 @@ int walker_targets_stdin(char ***target, const char ***write_ref)\n \n \t\tif (targets >= targets_alloc) {\n \t\t\ttargets_alloc = targets_alloc ? targets_alloc * 2 : 64;\n-\t\t\t*target = xrealloc(*target, targets_alloc * sizeof(**target));\n-\t\t\t*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));\n+\t\t\tREALLOC_ARRAY(*target, targets_alloc);\n+\t\t\tREALLOC_ARRAY(*write_ref, targets_alloc);\n \t\t}\n \t\t(*target)[targets] = xstrdup(tg_one);\n \t\t(*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;\n-- \n2.1.0\n"},{"id":"249520","messageId":"xmqqy4tj1i39.fsf@gitster.dls.corp.google.com","threadId":"37563","inReplyTo":"541886D5.8060202@web.de","subject":"Re: [PATCH 1/2] add macro REALLOCARRAY","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-09-16T19:27:38Z","receivedAt":"2014-09-16T19:27:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> Am 16.09.2014 um 05:04 schrieb Junio C Hamano:\n>> On Sun, Sep 14, 2014 at 9:55 AM, René Scharfe <l.s.r@web.de> wrote:\n>>> +#define REALLOCARRAY(x, alloc) x = xrealloc((x), (alloc) * sizeof(*(x)))\n>>\n>> I have been wondering if \"x\" could be an expression that has an operator\n>> that binds weaker than the assignment '='.  That may necessitate the LHS\n>> of the assignment to be somehow marked as bound the tightest, i.e.\n>>\n>> #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))\n>>\n>> Or am I being overly silly?\n>\n> ALLOC_GROW did well without that.  I can't think of a good use case\n> for a complex expression on the right-hand side.  That said, I think I\n> still have a spare matching pair of parentheses lying around here\n> somewhere, so let's play it safe and use them. :)\n\nYeah, as long as (any) is still an lvalue for any lvalue for\neverybody's compiler, (x) = ... expression ... is safer, but\ntaking cue from ALLOC_GROW(), I would say I was probably being\nslightly overly silly.\n"},{"id":"249592","messageId":"20140917081753.GC16200@peff.net","threadId":"37563","inReplyTo":"xmqqtx487nej.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH 1/2] add macro REALLOCARRAY","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-09-17T08:17:54Z","receivedAt":"2014-09-17T08:17:54Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Sep 15, 2014 at 11:24:04AM -0700, Junio C Hamano wrote:\n\n> René Scharfe <l.s.r@web.de> writes:\n> \n> > The macro ALLOC_GROW manages several aspects of dynamic memory\n> > allocations for arrays: It performs overprovisioning in order to avoid\n> > reallocations in future calls, updates the allocation size variable,\n> > multiplies the item size and thus allows users to simply specify the\n> > item count, performs the reallocation and updates the array pointer.\n> >\n> > Sometimes this is too much.  Add the macro REALLOCARRAY, which only\n> > takes care of the latter three points and allows users to specify the\n> > number of items an array can store directly.  It can increase and\n> > also decrease its size.  Using this macro avoids duplicating the\n> > array pointer name and takes care of item sizes automatically.\n> >\n> > Signed-off-by: Rene Scharfe <l.s.r@web.de>\n> > ---\n> \n> Makes sense.  Originally I had two minor gripes against this\n> \n>  #1 a macro that modifies its arguments feels a bit too magical, and\n>     we would not want to overuse them.\n\nThis is probably getting into the too-magical territory, but I have long\nconsidered a macro like:\n\n  #define ALLOC(x) (x) = xmalloc(sizeof(*x))\n\nto prevent obvious size-mismatch errors.  You could even call the macro\nNEW() if you wanted to be really disgusting. :)\n\nI rejected it as probably too cutesy (and non-idiomatic for experienced\nC programmers), but I feel like this REALLOC_ARRAY is basically the same\nthing. I dunno. It does make the code a bit more readable, once you\nunderstand what the macro is doing.\n\n-Peff\n"},{"id":"249823","messageId":"54227379.5010708@alum.mit.edu","threadId":"37563","inReplyTo":"541887F0.1050007@web.de","subject":"Re: [PATCH 1/2] add macro REALLOC_ARRAY","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2014-09-24T07:32:09Z","receivedAt":"2014-09-24T07:32:09Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 09/16/2014 08:56 PM, René Scharfe wrote:\n> The macro ALLOC_GROW manages several aspects of dynamic memory\n> allocations for arrays: It performs overprovisioning in order to avoid\n> reallocations in future calls, updates the allocation size variable,\n> multiplies the item size and thus allows users to simply specify the\n> item count, performs the reallocation and updates the array pointer.\n> \n> Sometimes this is too much.  Add the macro REALLOC_ARRAY, which only\n> takes care of the latter three points and allows users to specfiy the\n> number of items the array can store.  It can increase and also decrease\n> the size.  Using the macro avoid duplicating the variable name and\n> takes care of the item sizes automatically.\n\nIs there a reason that ALLOC_GROW and REALLOC_ARRAY are defined in two\nseparate header files (cache.h and git-compat-util.h, respectively)? It\nseems to me that they are close siblings and therefore I find it\nsurprising that they are not defined right next to each other.\n\nIt's true that ALLOC_GROW contains a *tiny* bit of application logic in\nthe form of the alloc_nr macro used to compute the new size of the\narray, but it's still pretty generic.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\n"},{"id":"249833","messageId":"xmqqbnq4hpby.fsf@gitster.dls.corp.google.com","threadId":"37563","inReplyTo":"54227379.5010708@alum.mit.edu","subject":"Re: [PATCH 1/2] add macro REALLOC_ARRAY","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-09-24T17:59:29Z","receivedAt":"2014-09-24T17:59:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> On 09/16/2014 08:56 PM, René Scharfe wrote:\n>> The macro ALLOC_GROW manages several aspects of dynamic memory\n>> allocations for arrays: It performs overprovisioning in order to avoid\n>> reallocations in future calls, updates the allocation size variable,\n>> multiplies the item size and thus allows users to simply specify the\n>> item count, performs the reallocation and updates the array pointer.\n>> \n>> Sometimes this is too much.  Add the macro REALLOC_ARRAY, which only\n>> takes care of the latter three points and allows users to specfiy the\n>> number of items the array can store.  It can increase and also decrease\n>> the size.  Using the macro avoid duplicating the variable name and\n>> takes care of the item sizes automatically.\n>\n> Is there a reason that ALLOC_GROW and REALLOC_ARRAY are defined in two\n> separate header files (cache.h and git-compat-util.h, respectively)? It\n> seems to me that they are close siblings and therefore I find it\n> surprising that they are not defined right next to each other.\n\nThat was my initial reaction, but on the other hand, because\nREALLOC_ARRAY() should never be used on an array managed by\nALLOC_GROW() without mucking with internal implementation details of\nwhat ALLOC_GROW() does yourself, there is not much reason for them\nto be listed and live together in the same place.\n\nListing them together might even invite confusion and mixed use by\nmistake.\n"},{"id":"249834","messageId":"20140924184740.GK1175@google.com","threadId":"37563","inReplyTo":"541887F9.3000100@web.de","subject":"Re: [PATCH 2/2] use REALLOC_ARRAY for changing the allocation size of arrays","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2014-09-24T18:47:40Z","receivedAt":"2014-09-24T18:47:40Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"René Scharfe wrote:\n\n> --- a/khash.h\n> +++ b/khash.h\n\n(not really about this patch) Where did this file come from?  Do we\nwant to be able to sync with upstream to get later bugfixes (e.g.,\nhttps://github.com/attractivechaos/klib/commit/000f0890)?  If so, it\nmight make sense to avoid unnecessary changes to the file so it's\neasier to see when it's safe to replace the file wholesale with a new\nversion.\n\nCurious,\nJonathan\n"},{"id":"249835","messageId":"54231B06.10700@web.de","threadId":"37563","inReplyTo":"54227379.5010708@alum.mit.edu","subject":"Re: [PATCH 1/2] add macro REALLOC_ARRAY","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-24T19:27:02Z","receivedAt":"2014-09-24T19:27:02Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 24.09.2014 um 09:32 schrieb Michael Haggerty:\n> Is there a reason that ALLOC_GROW and REALLOC_ARRAY are defined in two\n> separate header files (cache.h and git-compat-util.h, respectively)? It\n> seems to me that they are close siblings and therefore I find it\n> surprising that they are not defined right next to each other.\n\nREALLOC_ARRAY is more like xrealloc and it's used in places that only \n#include git-compat-util.h and not cache.h, so the first header was the \nright place.\n\nALLOC_GROW could be moved there in a separate patch, but I'm not sure \nit's worth it.\n\nRené\n"},{"id":"249836","messageId":"54231B1D.7070807@web.de","threadId":"37563","inReplyTo":"20140924184740.GK1175@google.com","subject":"Re: [PATCH 2/2] use REALLOC_ARRAY for changing the allocation size of arrays","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2014-09-24T19:27:25Z","receivedAt":"2014-09-24T19:27:25Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 24.09.2014 um 20:47 schrieb Jonathan Nieder:\n> René Scharfe wrote:\n>\n>> --- a/khash.h\n>> +++ b/khash.h\n>\n> (not really about this patch) Where did this file come from?  Do we\n> want to be able to sync with upstream to get later bugfixes (e.g.,\n> https://github.com/attractivechaos/klib/commit/000f0890)?  If so, it\n> might make sense to avoid unnecessary changes to the file so it's\n> easier to see when it's safe to replace the file wholesale with a new\n> version.\n\nTrue.  For this patch we're safe, I think, because it already called \nxrealloc before I touched it (and has been doing that since it was \nimported into git).\n\nRené\n"}]}