From 07a774a28755d0a31446f64a53c2be62c27e232d Mon Sep 17 00:00:00 2001 From: Bruce Cowan <bruce@bcowan.me.uk> Date: Tue, 24 Dec 2019 14:15:17 +0000 Subject: [PATCH] Better memory handling --- lib/types/array.c | 54 +++++++++++++++++++++---------------------- lib/types/hashtable.c | 6 ++--- lib/utils/mem.c | 40 +++++++++++++++++++++++--------- lib/utils/mem.h | 9 +++++--- lib/utils/meson.build | 4 ++-- meson.build | 22 ++++++++++++++---- 6 files changed, 84 insertions(+), 51 deletions(-) diff --git a/lib/types/array.c b/lib/types/array.c index 59b3bbc..97c9cdc 100644 --- a/lib/types/array.c +++ b/lib/types/array.c @@ -49,15 +49,15 @@ resize_array (Array *array, size = (size_t) ceil (size * 1.5); } - array->data = check_realloc (array->data, sizeof (void *) * size); + array->data = check_reallocarray (array->data, size, sizeof (void *)); array->capacity = size; } static bool index_in_array (const Array *array, - size_t index) + size_t idx) { - if (index < array->length) + if (idx < array->length) return true; else { @@ -86,7 +86,7 @@ array_new (FreeFunc func) { Array *array = check_malloc (sizeof (Array)); - array->data = check_malloc (sizeof (void *) * MIN_SIZE); + array->data = check_calloc (MIN_SIZE, sizeof (void *)); array->length = 0; array->capacity = MIN_SIZE; array->free_func = func; @@ -157,7 +157,7 @@ array_add (Array *array, /** * array_remove_fast: * @array: An array - * @index: The index of the item to remove from @array + * @idx: The index of the item to remove from @array * * Removes an item from an array. This function copies the last member of the * array to the location of the item to be removed, which means that ordering @@ -167,19 +167,19 @@ array_add (Array *array, */ bool array_remove_fast (Array *array, - size_t index) + size_t idx) { - if (!index_in_array (array, index)) + if (!index_in_array (array, idx)) { perror ("array_remove_fast"); return false; } if (array->free_func) - array->free_func (array->data[index]); + array->free_func (array->data[idx]); void *last = array->data[array->length - 1]; - array->data[index] = last; + array->data[idx] = last; array->length -= 1; maybe_shrink (array); @@ -190,7 +190,7 @@ array_remove_fast (Array *array, /** * array_remove: * @array: An array - * @index: The index of the item to remove from @array + * @idx: The index of the item to remove from @array * * Removes an item from an array. This function moves the items following the * removed item down one space. This preserves the ordering of the items, but is @@ -200,20 +200,20 @@ array_remove_fast (Array *array, */ bool array_remove (Array *array, - size_t index) + size_t idx) { - if (!index_in_array (array, index)) + if (!index_in_array (array, idx)) { perror ("array_remove"); return false; } if (array->free_func) - array->free_func (array->data[index]); + array->free_func (array->data[idx]); - memmove (array->data + index, - array->data + index + 1, - sizeof (void *) * (array->length - index - 1)); + memmove (array->data + idx, + array->data + idx + 1, + sizeof (void *) * (array->length - idx - 1)); array->length -= 1; maybe_shrink (array); @@ -224,43 +224,43 @@ array_remove (Array *array, /** * array_set: * @array: An array - * @index: The index of the item to set a value for + * @idx: The index of the item to set a value for * @val: The value to set the item to * - * Sets an element of @array to @val, using the @index. + * Sets an element of @array to @val, using the @idx. * * Returns: %true if successful */ bool array_set (Array *array, - size_t index, + size_t idx, const void *val) { - if (!index_in_array (array, index)) + if (!index_in_array (array, idx)) { perror ("array_set"); return false; } - array->data[index] = (void *) val; + array->data[idx] = (void *) val; return true; } /** * array_get: * @array: An array - * @index: The index of @array to get a value from + * @idx: The index of @array to get a value from * - * Get a value of @array, using @index. + * Get a value of @array, using @idx. * - * Returns: (transfer none): The value at @index of @array + * Returns: (transfer none): The value at @idx of @array */ const void * array_get (const Array *array, - size_t index) + size_t idx) { - if (index_in_array (array, index)) - return array->data[index]; + if (index_in_array (array, idx)) + return array->data[idx]; else { perror ("array_get"); diff --git a/lib/types/hashtable.c b/lib/types/hashtable.c index 7cbe6a7..4eed6ef 100644 --- a/lib/types/hashtable.c +++ b/lib/types/hashtable.c @@ -145,11 +145,11 @@ hash_table_insert (HashTable *table, const void *key, const void *value) { - unsigned index = table->hash_func (key) % HASH_SIZE; + unsigned idx = table->hash_func (key) % HASH_SIZE; KeyValue *kv = key_value_new (key, value); - SList *list = slist_prepend (table->array[index], kv); - table->array[index] = list; + SList *list = slist_prepend (table->array[idx], kv); + table->array[idx] = list; } /** diff --git a/lib/utils/mem.c b/lib/utils/mem.c index 168c1e6..588afbc 100644 --- a/lib/utils/mem.c +++ b/lib/utils/mem.c @@ -1,6 +1,6 @@ /* mem.c * - * Copyright 2018 Bruce Cowan <bruce@bcowan.me.uk> + * Copyright 2018, 2019 Bruce Cowan <bruce@bcowan.me.uk> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,27 +17,45 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "config.h" #include "mem.h" #include <stdlib.h> +void * +check_calloc (size_t nmemb, + size_t size) +{ + void *ptr = calloc (nmemb, size); + if (!ptr) + exit (EXIT_FAILURE); + + return ptr; +} + void * check_malloc (size_t size) { - void *ptr = malloc (size); - if (!ptr) - exit (EXIT_FAILURE); + void *ptr = malloc (size); + if (!ptr) + exit (EXIT_FAILURE); - return ptr; + return ptr; } void * -check_realloc (void *ptr, - size_t size) +check_reallocarray (void *ptr, + size_t nmemb, + size_t size) { - void *new = realloc (ptr, size); - if (!new) - exit (EXIT_FAILURE); +#ifdef HAVE_REALLOCARRAY + void *new = reallocarray (ptr, nmemb, size); +#else + void *new = realloc (ptr, nmemb * size); +#endif + + if (!new) + exit (EXIT_FAILURE); - return new; + return ptr; } diff --git a/lib/utils/mem.h b/lib/utils/mem.h index c73b025..335fab2 100644 --- a/lib/utils/mem.h +++ b/lib/utils/mem.h @@ -21,6 +21,9 @@ #include <stddef.h> -void * check_malloc (size_t size); -void * check_realloc (void *ptr, - size_t size); +void * check_calloc (size_t nmemb, + size_t size); +void * check_malloc (size_t size); +void * check_reallocarray (void *ptr, + size_t nmemb, + size_t size); diff --git a/lib/utils/meson.build b/lib/utils/meson.build index 90621de..94f97d8 100644 --- a/lib/utils/meson.build +++ b/lib/utils/meson.build @@ -1,3 +1,3 @@ -utils_lib = library('utils', ['mem.c', 'utils.c']) +utils_lib = library('utils', ['mem.c', 'utils.c'], dependencies: config_dep) utils_dep = declare_dependency(link_with: utils_lib, - include_directories: '.') + include_directories: '.') diff --git a/meson.build b/meson.build index 67955c4..5b05a65 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,5 @@ -project('stdlib', 'c') +project('stdlib', 'c', + default_options: ['c_std=gnu99']) cc = meson.get_compiler('c') libm = cc.find_library('m') @@ -7,16 +8,27 @@ glib_dep = dependency('glib-2.0', version: '>= 2.16', required: false) openmp_dep = dependency('openmp', required: false) thread_dep = dependency('threads', required: false) +conf_data = configuration_data() + +cc = meson.get_compiler('c') + +has_reallocarray = cc.has_function('reallocarray') +if cc.has_function('reallocarray') + conf_data.set('HAVE_REALLOCARRAY', 1) +endif + +configure_file(configuration: conf_data, output: 'config.h') +config_dep = declare_dependency(include_directories: '.') + if host_machine.system() == 'windows' - cc = meson.get_compiler('c') - socket_deps = [cc.find_library('ws2_32')] + socket_deps = [cc.find_library('ws2_32')] else - socket_deps = [] + socket_deps = [] endif subdir('lib') subdir('src') if glib_dep.found() - subdir('test') + subdir('test') endif -- GitLab