diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ff68483..89e97bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,4 +25,5 @@ jobs: steps: - uses: actions/checkout@v2 - run: sudo apt install -y valgrind - - run: make valgrind + - run: make test_valgrind + - run: valgrind --leak-check=full --error-exitcode=1 ./ContainersTestValgrind diff --git a/Makefile b/Makefile index bcb032a..4afaa4f 100644 --- a/Makefile +++ b/Makefile @@ -31,8 +31,7 @@ test_optimized: test_coverage: @gcc src/*.c tst/*.c -Wall -Wextra -Wpedantic -Werror -std=c89 -O0 -ldl -g -coverage -o ContainersTestCoverage -valgrind: +test_valgrind: @sed -i 's/STUB_MALLOC 1/STUB_MALLOC 0/g' tst/test.h @gcc src/*.c tst/*.c -Wall -Wextra -Wpedantic -Werror -std=c89 -O0 -o ContainersTestValgrind @sed -i 's/STUB_MALLOC 0/STUB_MALLOC 1/g' tst/test.h - @valgrind --leak-check=full ./ContainersTestValgrind diff --git a/src/multimap.c b/src/multimap.c index 0c13a31..0334a95 100644 --- a/src/multimap.c +++ b/src/multimap.c @@ -306,7 +306,7 @@ static void multimap_insert_balance(multimap me, char *const item) */ static char *multimap_create_value_node(multimap me, const void *const value) { - char *const add = malloc(sizeof(char *) + me->value_size); + char *const add = malloc(ptr_size + me->value_size); if (!add) { return NULL; } @@ -321,8 +321,7 @@ static char *multimap_create_value_node(multimap me, const void *const value) static char *multimap_create_node(multimap me, const void *const key, const void *const value, char *const parent) { - const size_t size = 1 + sizeof(size_t) + 4 * sizeof(char *) + me->key_size; - char *const insert = malloc(size); + char *const insert = malloc(1 + count_size + 4 * ptr_size + me->key_size); const size_t one = 1; char *value_node; if (!insert) { @@ -495,7 +494,7 @@ void multimap_get_start(multimap me, void *const key) * @param value the value to be copied to from iteration * @param me the multi-map to iterate over * - * @return 1 if there exist no more values for the key which is being iterated + * @return 1 if there exist more values for the key which is being iterated * over, otherwise 0 */ int multimap_get_next(void *const value, multimap me) @@ -836,7 +835,7 @@ int multimap_remove(multimap me, void *const key, void *const value) if (me->value_comparator(current_value_node + value_node_value_offset, value) == 0) { memcpy(traverse + node_value_head_offset, - current_value_node + node_value_head_offset, ptr_size); + current_value_node + value_node_next_offset, ptr_size); } else { char *previous_value_node = current_value_node; memcpy(¤t_value_node, current_value_node + value_node_next_offset, diff --git a/src/unordered_map.c b/src/unordered_map.c index 684d694..c9b23ac 100644 --- a/src/unordered_map.c +++ b/src/unordered_map.c @@ -234,7 +234,7 @@ static char *unordered_map_create_element(unordered_map me, const void *const key, const void *const value) { - char *init = malloc(ptr_size + hash_size + me->key_size); + char *init = malloc(ptr_size + hash_size + me->key_size + me->value_size); if (!init) { return NULL; } @@ -425,6 +425,7 @@ int unordered_map_clear(unordered_map me) free(backup); } } + free(me->buckets); me->size = 0; me->capacity = STARTING_BUCKETS; me->buckets = updated_buckets; diff --git a/src/unordered_multimap.c b/src/unordered_multimap.c index 951c431..bde3047 100644 --- a/src/unordered_multimap.c +++ b/src/unordered_multimap.c @@ -253,7 +253,7 @@ static char *unordered_multimap_create_element(unordered_multimap me, const void *const key, const void *const value) { - char *init = malloc(ptr_size + hash_size + me->key_size); + char *init = malloc(ptr_size + hash_size + me->key_size + me->value_size); if (!init) { return NULL; } @@ -356,7 +356,7 @@ void unordered_multimap_get_start(unordered_multimap me, void *const key) * @param value the value to be copied to from iteration * @param me the unordered multi-map to iterate over * - * @return 1 if there exist no more values for the key which is being iterated + * @return 1 if there exist more values for the key which is being iterated * over, otherwise 0 */ int unordered_multimap_get_next(void *const value, unordered_multimap me) @@ -559,6 +559,7 @@ int unordered_multimap_clear(unordered_multimap me) free(backup); } } + free(me->buckets); me->size = 0; me->capacity = STARTING_BUCKETS; me->buckets = updated_buckets; diff --git a/src/unordered_multiset.c b/src/unordered_multiset.c index d9e4bd2..052317b 100644 --- a/src/unordered_multiset.c +++ b/src/unordered_multiset.c @@ -483,6 +483,7 @@ int unordered_multiset_clear(unordered_multiset me) free(backup); } } + free(me->buckets); me->size = 0; me->capacity = STARTING_BUCKETS; me->used = 0; diff --git a/src/unordered_set.c b/src/unordered_set.c index aa8da93..50a2276 100644 --- a/src/unordered_set.c +++ b/src/unordered_set.c @@ -381,6 +381,7 @@ int unordered_set_clear(unordered_set me) free(backup); } } + free(me->buckets); me->size = 0; me->capacity = STARTING_BUCKETS; me->buckets = updated_buckets; diff --git a/tst/test_array.c b/tst/test_array.c index 5f4c317..0de7cab 100644 --- a/tst/test_array.c +++ b/tst/test_array.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/array.h" @@ -85,6 +86,45 @@ static void test_init_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + array me = array_init(16, sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(array_set(me, i, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(array_get(&b, me, i) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!array_destroy(me)); +} + void test_array(void) { test_invalid_init(); @@ -93,4 +133,5 @@ void test_array(void) #if STUB_MALLOC test_init_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_deque.c b/tst/test_deque.c index 5110b4a..8f1dc0c 100644 --- a/tst/test_deque.c +++ b/tst/test_deque.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/deque.h" @@ -420,6 +421,45 @@ static int test_puzzle(int start_node, int dest_node) return -1; } +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + deque me = deque_init(sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(deque_push_front(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(deque_pop_back(&b, me) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!deque_destroy(me)); +} + void test_deque(void) { test_invalid_init(); @@ -440,4 +480,5 @@ void test_deque(void) test_single_full_block(); assert(test_puzzle(2, 5) == 4); assert(test_puzzle(2, 10) == 5); + test_big_object(); } diff --git a/tst/test_forward_list.c b/tst/test_forward_list.c index f0dedeb..e572c71 100644 --- a/tst/test_forward_list.c +++ b/tst/test_forward_list.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/forward_list.h" @@ -342,6 +343,46 @@ static int test_puzzle_backwards(int start_node, int dest_node) return -1; } +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + forward_list me = forward_list_init(sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(forward_list_add_first(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(forward_list_get_last(&b, me) == 0); + assert(forward_list_remove_last(me) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!forward_list_destroy(me)); +} + void test_forward_list(void) { test_invalid_init(); @@ -357,4 +398,5 @@ void test_forward_list(void) assert(test_puzzle_forwards(2, 10) == 5); assert(test_puzzle_backwards(2, 5) == 4); assert(test_puzzle_backwards(2, 10) == 5); + test_big_object(); } diff --git a/tst/test_list.c b/tst/test_list.c index 762d9b6..a2867c1 100644 --- a/tst/test_list.c +++ b/tst/test_list.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/list.h" @@ -335,6 +336,46 @@ static int test_puzzle_backwards(int start_node, int dest_node) return -1; } +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + list me = list_init(sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(list_add_first(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(list_get_last(&b, me) == 0); + assert(list_remove_last(me) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!list_destroy(me)); +} + void test_list(void) { test_invalid_init(); @@ -350,4 +391,5 @@ void test_list(void) assert(test_puzzle_forwards(2, 10) == 5); assert(test_puzzle_backwards(2, 5) == 4); assert(test_puzzle_backwards(2, 10) == 5); + test_big_object(); } diff --git a/tst/test_map.c b/tst/test_map.c index 483494c..3a9b424 100644 --- a/tst/test_map.c +++ b/tst/test_map.c @@ -1,3 +1,4 @@ +#include #include #include "test.h" #include "../src/include/map.h" @@ -552,6 +553,53 @@ static void test_put_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static void test_big_object(void) +{ + int i; + map me = map_init(sizeof(int), sizeof(struct big_object), + compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(map_put(me, &i, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(map_get(&b, me, &i) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!map_destroy(me)); +} + void test_map(void) { test_invalid_init(); @@ -567,4 +615,5 @@ void test_map(void) test_init_out_of_memory(); test_put_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_multimap.c b/tst/test_multimap.c index 2fd1332..85b0503 100644 --- a/tst/test_multimap.c +++ b/tst/test_multimap.c @@ -1,3 +1,4 @@ +#include #include #include "test.h" #include "../src/include/multimap.h" @@ -617,6 +618,60 @@ static void test_put_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static int compare_dummy() +{ + assert(0); +} + +static void test_big_object(void) +{ + int i; + multimap me = multimap_init(sizeof(int), sizeof(struct big_object), + compare_big_object, compare_dummy); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(multimap_put(me, &i, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + multimap_get_start(me, &i); + assert(multimap_get_next(&b, me) == 1); + assert(multimap_get_next(&b, me) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!multimap_destroy(me)); +} + void test_multimap(void) { test_invalid_init(); @@ -633,4 +688,5 @@ void test_multimap(void) test_init_out_of_memory(); test_put_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_multiset.c b/tst/test_multiset.c index 0436497..7993c78 100644 --- a/tst/test_multiset.c +++ b/tst/test_multiset.c @@ -1,3 +1,4 @@ +#include #include #include "test.h" #include "../src/include/multiset.h" @@ -553,6 +554,57 @@ static void test_put_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static void test_big_object(void) +{ + int i; + multiset me = multiset_init(sizeof(struct big_object), compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(multiset_put(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(multiset_contains(me, &b) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!multiset_destroy(me)); +} + void test_multiset(void) { test_invalid_init(); @@ -568,4 +620,5 @@ void test_multiset(void) test_init_out_of_memory(); test_put_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_priority_queue.c b/tst/test_priority_queue.c index ae64a30..3a8e117 100644 --- a/tst/test_priority_queue.c +++ b/tst/test_priority_queue.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/vector.h" #include "../src/include/priority_queue.h" @@ -182,6 +183,54 @@ static void test_push_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + /* Bigger number = lower priority */ + return b->n - a->n; +} + +static void test_big_object(void) +{ + int i; + priority_queue me = priority_queue_init(sizeof(struct big_object), + compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(priority_queue_push(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(priority_queue_pop(&b, me) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!priority_queue_destroy(me)); +} + void test_priority_queue(void) { test_invalid_init(); @@ -190,4 +239,5 @@ void test_priority_queue(void) test_init_out_of_memory(); test_push_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_queue.c b/tst/test_queue.c index d30cf85..df196c7 100644 --- a/tst/test_queue.c +++ b/tst/test_queue.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/queue.h" @@ -140,6 +141,45 @@ static int test_puzzle(int start_node, int dest_node) return -1; } +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + queue me = queue_init(sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(queue_push(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(queue_pop(&b, me) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!queue_destroy(me)); +} + void test_queue(void) { test_invalid_init(); @@ -148,4 +188,5 @@ void test_queue(void) test_automated_trim(); assert(test_puzzle(2, 5) == 4); assert(test_puzzle(2, 10) == 5); + test_big_object(); } diff --git a/tst/test_set.c b/tst/test_set.c index 6bdc830..87df060 100644 --- a/tst/test_set.c +++ b/tst/test_set.c @@ -1,3 +1,4 @@ +#include #include #include "test.h" #include "../src/include/set.h" @@ -522,6 +523,57 @@ static void test_put_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static void test_big_object(void) +{ + int i; + set me = set_init(sizeof(struct big_object), compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(set_put(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(set_contains(me, &b) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!set_destroy(me)); +} + void test_set(void) { test_invalid_init(); @@ -536,4 +588,5 @@ void test_set(void) test_init_out_of_memory(); test_put_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_stack.c b/tst/test_stack.c index f0c37b6..804058e 100644 --- a/tst/test_stack.c +++ b/tst/test_stack.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/stack.h" @@ -67,9 +68,49 @@ static void test_automated_trim(void) assert(!stack_destroy(me)); } +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + stack me = stack_init(sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(stack_push(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 15; i >= 0; i--) { + int j; + struct big_object b; + assert(stack_pop(&b, me) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!stack_destroy(me)); +} + void test_stack(void) { test_invalid_init(); test_basic(); test_automated_trim(); + test_big_object(); } diff --git a/tst/test_unordered_map.c b/tst/test_unordered_map.c index aca644a..7b1ab24 100644 --- a/tst/test_unordered_map.c +++ b/tst/test_unordered_map.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/unordered_map.h" @@ -291,6 +292,54 @@ static void test_clear_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static void test_big_object(void) +{ + int i; + unordered_map me = unordered_map_init(sizeof(int), + sizeof(struct big_object), + bad_hash_int, compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(unordered_map_put(me, &i, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(unordered_map_get(&b, me, &i) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!unordered_map_destroy(me)); +} + void test_unordered_map(void) { test_invalid_init(); @@ -303,4 +352,5 @@ void test_unordered_map(void) test_resize_out_of_memory(); test_clear_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_unordered_multimap.c b/tst/test_unordered_multimap.c index 222457d..483233f 100644 --- a/tst/test_unordered_multimap.c +++ b/tst/test_unordered_multimap.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/unordered_multimap.h" @@ -401,6 +402,63 @@ static void test_clear_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static int compare_dummy() +{ + assert(0); +} + +static void test_big_object(void) +{ + int i; + unordered_multimap me = unordered_multimap_init(sizeof(int), + sizeof(struct big_object), + bad_hash_int, + compare_big_object, + compare_dummy); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(unordered_multimap_put(me, &i, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + unordered_multimap_get_start(me, &i); + assert(unordered_multimap_get_next(&b, me) == 1); + assert(unordered_multimap_get_next(&b, me) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!unordered_multimap_destroy(me)); +} + void test_unordered_multimap(void) { test_invalid_init(); @@ -415,4 +473,5 @@ void test_unordered_multimap(void) test_resize_out_of_memory(); test_clear_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_unordered_multiset.c b/tst/test_unordered_multiset.c index 8c4bb62..3016d0b 100644 --- a/tst/test_unordered_multiset.c +++ b/tst/test_unordered_multiset.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/unordered_multiset.h" @@ -333,6 +334,59 @@ static void test_clear_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static void test_big_object(void) +{ + int i; + unordered_multiset me = unordered_multiset_init(sizeof(struct big_object), + bad_hash_int, + compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(unordered_multiset_put(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(unordered_multiset_contains(me, &b) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!unordered_multiset_destroy(me)); +} + void test_unordered_multiset(void) { test_invalid_init(); @@ -346,4 +400,5 @@ void test_unordered_multiset(void) test_resize_out_of_memory(); test_clear_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_unordered_set.c b/tst/test_unordered_set.c index f8d88cc..1049ff1 100644 --- a/tst/test_unordered_set.c +++ b/tst/test_unordered_set.c @@ -1,3 +1,4 @@ +#include #include "test.h" #include "../src/include/unordered_set.h" @@ -275,6 +276,58 @@ static void test_clear_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static int compare_big_object(const void *const one, const void *const two) +{ + const struct big_object *const a = one; + const struct big_object *const b = two; + return a->n - b->n; +} + +static void test_big_object(void) +{ + int i; + unordered_set me = unordered_set_init(sizeof(struct big_object), + bad_hash_int, compare_big_object); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(unordered_set_put(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(unordered_set_contains(me, &b) == 1); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!unordered_set_destroy(me)); +} + void test_unordered_set(void) { test_invalid_init(); @@ -287,4 +340,5 @@ void test_unordered_set(void) test_resize_out_of_memory(); test_clear_out_of_memory(); #endif + test_big_object(); } diff --git a/tst/test_vector.c b/tst/test_vector.c index 185c73c..309babd 100644 --- a/tst/test_vector.c +++ b/tst/test_vector.c @@ -1,3 +1,4 @@ +#include #include #include "test.h" #include "../src/include/vector.h" @@ -272,6 +273,46 @@ static void test_add_out_of_memory(void) } #endif +struct big_object { + int n; + double d; + signed char c[8]; +}; + +static void test_big_object(void) +{ + int i; + vector me = vector_init(sizeof(struct big_object)); + assert(me); + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + b.n = INT_MIN + i; + b.d = i + 0.5; + for (j = 0; j < 8; j++) { + b.c[j] = (signed char) (SCHAR_MIN + i + j); + } + assert(vector_add_first(me, &b) == 0); + b.n = -1; + b.d = -1; + for (j = 0; j < 8; j++) { + b.c[j] = -1; + } + } + for (i = 0; i < 16; i++) { + int j; + struct big_object b; + assert(vector_get_last(&b, me) == 0); + assert(vector_remove_last(me) == 0); + assert(b.n == INT_MIN + i); + assert(b.d == i + 0.5); + for (j = 0; j < 8; j++) { + assert(b.c[j] == SCHAR_MIN + i + j); + } + } + assert(!vector_destroy(me)); +} + void test_vector(void) { test_invalid_init(); @@ -283,4 +324,5 @@ void test_vector(void) test_set_space_out_of_memory(); test_add_out_of_memory(); #endif + test_big_object(); }