[pacman-dev] [PATCHv2 2/5] util: Add _alpm_realloc()
Andrew Gregory
andrew.gregory.8 at gmail.com
Thu Jan 30 10:48:22 EST 2014
On 01/28/14 at 11:12am, Florian Pritz wrote:
> Signed-off-by: Florian Pritz <bluewind at xinu.at>
> ---
> v2:
> - Incorporated suggestions by Dave (take **data instead of *data)
> - Handle overflows
>
> RFC:
> systemd's greedy_realloc0() uses uint8_t instead of char for *newdata.
> Is that important or doesn't matter?
>
>
> lib/libalpm/util.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> lib/libalpm/util.h | 1 +
> 2 files changed, 47 insertions(+)
>
> diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
> index 1bbc768..753cdd7 100644
> --- a/lib/libalpm/util.c
> +++ b/lib/libalpm/util.c
> @@ -1287,6 +1287,52 @@ int _alpm_fnmatch(const void *pattern, const void *string)
> return fnmatch(pattern, string, 0);
> }
>
> +/**
> + * Think of this as realloc with error handling and
> + * automatic growing based on current/required
> + *
> + * @param data source memory space
> + * @param current size of the space pointed to be data
> + * @param required size you want
> + * @return new memory
> + */
This should mention the fact that this is grow-only and "greedy" so
required is really the minimum needed and won't be the final size.
A note about possibly handing back unused portions of the allocated
memory might not hurt either.
> +void *_alpm_realloc(void **data, size_t *current, const size_t required)
> +{
> + size_t old_size = *current;
This variable is entirely unnecessary because you don't update current
until you're about to return.
> + char *newdata;
> + size_t newsize = *current;
> +
> + if(*current >= required) {
> + return data;
> + }
> +
> + if(*current == 0) {
> + newsize = ALPM_BUFFER_SIZE;
> + } else if (required > (*current) * 2) {
> + newsize = required * 2;
> + } else {
> + newsize *= 2;
I think this will read better if you set newsize = current * 2 here
instead of setting newsize = current above and doubling it.
> + }
> +
> + /* check for overflows */
> + if (newsize < required) {
> + return NULL;
> + }
> +
> + newdata = realloc(*data, newsize);
> + if(!newdata) {
> + _alpm_alloc_fail(newsize);
> + return NULL;
> + }
> +
> + /* ensure all new memory is zeroed out, in both the initial
> + * allocation and later reallocs */
> + memset(newdata + old_size, 0, *current - old_size);
This does nothing because *current still equals old_size.
> + *current = newsize;
> + *data = newdata;
> + return newdata;
> +}
> +
> void _alpm_alloc_fail(size_t size)
> {
> fprintf(stderr, "alloc failure: could not allocate %zd bytes\n", size);
> diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
> index b566868..031254a 100644
> --- a/lib/libalpm/util.h
> +++ b/lib/libalpm/util.h
> @@ -141,6 +141,7 @@ int _alpm_raw_ncmp(const char *first, const char *second, size_t max);
> int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode);
> int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string);
> int _alpm_fnmatch(const void *pattern, const void *string);
> +void *_alpm_realloc(void **data, size_t *current, const size_t required);
>
> #ifndef HAVE_STRSEP
> char *strsep(char **, const char *);
> --
> 1.8.5.3
More information about the pacman-dev
mailing list