improve testing allocator + add tests for it

Sat, 16 Apr 2022 20:17:01 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 16 Apr 2022 20:17:01 +0200
changeset 518
74d0372f5c6f
parent 517
b3baaf9b7e3c
child 519
79d14e821b3a

improve testing allocator + add tests for it

test/CMakeLists.txt file | annotate | diff | comparison | revisions
test/test_list.cpp file | annotate | diff | comparison | revisions
test/util_allocator.c file | annotate | diff | comparison | revisions
test/util_allocator.cpp file | annotate | diff | comparison | revisions
test/util_allocator.h file | annotate | diff | comparison | revisions
     1.1 --- a/test/CMakeLists.txt	Sat Apr 16 18:02:10 2022 +0200
     1.2 +++ b/test/CMakeLists.txt	Sat Apr 16 20:17:01 2022 +0200
     1.3 @@ -18,7 +18,7 @@
     1.4          test_list.cpp
     1.5          test_tree.cpp
     1.6          selftest.cpp
     1.7 -        util_allocator.c
     1.8 +        util_allocator.cpp
     1.9          )
    1.10  target_link_libraries(ucxtest PRIVATE ucx_static gtest_main)
    1.11  gtest_discover_tests(ucxtest)
     2.1 --- a/test/test_list.cpp	Sat Apr 16 18:02:10 2022 +0200
     2.2 +++ b/test/test_list.cpp	Sat Apr 16 20:17:01 2022 +0200
     2.3 @@ -552,13 +552,11 @@
     2.4  class HighLevelTest : public ::testing::Test {
     2.5      mutable std::unordered_set<CxList *> lists;
     2.6  protected:
     2.7 -    void SetUp() override {
     2.8 -        cxTestingAllocatorReset();
     2.9 -    }
    2.10 +    CxTestingAllocator testingAllocator;
    2.11  
    2.12      void TearDown() override {
    2.13          for (auto &&l: lists) cxListDestroy(l);
    2.14 -        EXPECT_TRUE(cxTestingAllocatorVerify());
    2.15 +        EXPECT_TRUE(testingAllocator.verify());
    2.16      }
    2.17  
    2.18      static constexpr size_t testdata_len = 250;
    2.19 @@ -572,7 +570,7 @@
    2.20      auto linkedListFromTestData() const -> CxList * {
    2.21          return autofree(
    2.22                  cxLinkedListFromArray(
    2.23 -                        cxTestingAllocator,
    2.24 +                        &testingAllocator,
    2.25                          cmp_int,
    2.26                          sizeof(int),
    2.27                          testdata_len,
    2.28 @@ -582,15 +580,15 @@
    2.29      }
    2.30  
    2.31      auto pointerLinkedListFromTestData() const -> CxList * {
    2.32 -        auto list = autofree(cxPointerLinkedListCreate(cxTestingAllocator, cmp_int));
    2.33 +        auto list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
    2.34          cx_for_n(i, testdata_len) cxListAdd(list, &testdata.data[i]);
    2.35          return list;
    2.36      }
    2.37  
    2.38 -    static void verifyCreate(CxList *list) {
    2.39 +    void verifyCreate(CxList *list) const {
    2.40          EXPECT_EQ(list->size, 0);
    2.41          EXPECT_EQ(list->capacity, (size_t) -1);
    2.42 -        EXPECT_EQ(list->allocator, cxTestingAllocator);
    2.43 +        EXPECT_EQ(list->allocator, &testingAllocator);
    2.44          EXPECT_EQ(list->cmpfunc, cmp_int);
    2.45      }
    2.46  
    2.47 @@ -736,41 +734,41 @@
    2.48  };
    2.49  
    2.50  TEST_F(LinkedList, cxLinkedListCreate) {
    2.51 -    CxList *list = autofree(cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)));
    2.52 +    CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int)));
    2.53      EXPECT_EQ(list->itemsize, sizeof(int));
    2.54      verifyCreate(list);
    2.55  }
    2.56  
    2.57  TEST_F(PointerLinkedList, cxPointerLinkedListCreate) {
    2.58 -    CxList *list = autofree(cxPointerLinkedListCreate(cxTestingAllocator, cmp_int));
    2.59 +    CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
    2.60      EXPECT_EQ(list->itemsize, sizeof(void *));
    2.61      verifyCreate(list);
    2.62  }
    2.63  
    2.64  TEST_F(LinkedList, cxLinkedListFromArray) {
    2.65 -    CxList *expected = autofree(cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)));
    2.66 +    CxList *expected = autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int)));
    2.67      cx_for_n (i, testdata_len) cxListAdd(expected, &testdata.data[i]);
    2.68 -    CxList *list = autofree(cxLinkedListFromArray(cxTestingAllocator, cmp_int, sizeof(int),
    2.69 +    CxList *list = autofree(cxLinkedListFromArray(&testingAllocator, cmp_int, sizeof(int),
    2.70                                                    testdata_len, testdata.data.data()));
    2.71      EXPECT_EQ(cxListCompare(list, expected), 0);
    2.72  }
    2.73  
    2.74  TEST_F(LinkedList, cxListAdd) {
    2.75 -    CxList *list = autofree(cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int)));
    2.76 +    CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int)));
    2.77      verifyAdd(list, false);
    2.78  }
    2.79  
    2.80  TEST_F(PointerLinkedList, cxListAdd) {
    2.81 -    CxList *list = autofree(cxPointerLinkedListCreate(cxTestingAllocator, cmp_int));
    2.82 +    CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
    2.83      verifyAdd(list, true);
    2.84  }
    2.85  
    2.86  TEST_F(LinkedList, cxListInsert) {
    2.87 -    verifyInsert(autofree(cxLinkedListCreate(cxTestingAllocator, cmp_int, sizeof(int))));
    2.88 +    verifyInsert(autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int))));
    2.89  }
    2.90  
    2.91  TEST_F(PointerLinkedList, cxListInsert) {
    2.92 -    verifyInsert(autofree(cxPointerLinkedListCreate(cxTestingAllocator, cmp_int)));
    2.93 +    verifyInsert(autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int)));
    2.94  }
    2.95  
    2.96  TEST_F(LinkedList, cxListRemove) {
    2.97 @@ -815,13 +813,13 @@
    2.98  
    2.99  TEST_F(LinkedList, InsertViaIterator) {
   2.100      int fivenums[] = {0, 1, 2, 3, 4, 5};
   2.101 -    CxList *list = autofree(cxLinkedListFromArray(cxTestingAllocator, cmp_int, sizeof(int), 5, fivenums));
   2.102 +    CxList *list = autofree(cxLinkedListFromArray(&testingAllocator, cmp_int, sizeof(int), 5, fivenums));
   2.103      verifyInsertViaIterator(list);
   2.104  }
   2.105  
   2.106  TEST_F(PointerLinkedList, InsertViaIterator) {
   2.107      int fivenums[] = {0, 1, 2, 3, 4, 5};
   2.108 -    CxList *list = autofree(cxPointerLinkedListCreate(cxTestingAllocator, cmp_int));
   2.109 +    CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
   2.110      cx_for_n (i, 5) cxListAdd(list, &fivenums[i]);
   2.111      verifyInsertViaIterator(list);
   2.112  }
     3.1 --- a/test/util_allocator.c	Sat Apr 16 18:02:10 2022 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,126 +0,0 @@
     3.4 -/*
     3.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 - *
     3.7 - * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     3.8 - *
     3.9 - * Redistribution and use in source and binary forms, with or without
    3.10 - * modification, are permitted provided that the following conditions are met:
    3.11 - *
    3.12 - *   1. Redistributions of source code must retain the above copyright
    3.13 - *      notice, this list of conditions and the following disclaimer.
    3.14 - *
    3.15 - *   2. Redistributions in binary form must reproduce the above copyright
    3.16 - *      notice, this list of conditions and the following disclaimer in the
    3.17 - *      documentation and/or other materials provided with the distribution.
    3.18 - *
    3.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    3.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    3.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    3.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    3.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    3.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    3.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    3.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    3.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    3.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.29 - * POSSIBILITY OF SUCH DAMAGE.
    3.30 - */
    3.31 -
    3.32 -#include "util_allocator.h"
    3.33 -#include <string.h>
    3.34 -
    3.35 -void cx_testing_allocator_add(cx_testing_allocator_s *data, void *ptr) {
    3.36 -    data->tracked[data->live] = ptr;
    3.37 -    data->live++;
    3.38 -}
    3.39 -
    3.40 -int cx_testing_allocator_remove(cx_testing_allocator_s *data, void *ptr) {
    3.41 -    for (int i = 0; i < data->live; i++) {
    3.42 -        if (data->tracked[i] == ptr) {
    3.43 -            data->tracked[i] = data->tracked[data->live - 1];
    3.44 -            data->live--;
    3.45 -            return 0;
    3.46 -        }
    3.47 -    }
    3.48 -    return 1;
    3.49 -}
    3.50 -
    3.51 -void *cx_malloc_testing(void *d, size_t n) {
    3.52 -    cx_testing_allocator_s *data = d;
    3.53 -    void *ptr = malloc(n);
    3.54 -    data->alloc_total++;
    3.55 -    if (ptr == NULL) {
    3.56 -        data->alloc_failed++;
    3.57 -    } else {
    3.58 -        cx_testing_allocator_add(data, ptr);
    3.59 -    }
    3.60 -    return ptr;
    3.61 -}
    3.62 -
    3.63 -void *cx_realloc_testing(void *d, void *mem, size_t n) {
    3.64 -    cx_testing_allocator_s *data = d;
    3.65 -    void *ptr = realloc(mem, n);
    3.66 -    if (ptr == mem) {
    3.67 -        return ptr;
    3.68 -    } else {
    3.69 -        data->alloc_total++;
    3.70 -        if (ptr == NULL) {
    3.71 -            data->alloc_failed++;
    3.72 -        } else {
    3.73 -            data->free_total++;
    3.74 -            if (cx_testing_allocator_remove(data, mem)) {
    3.75 -                data->free_failed++;
    3.76 -            }
    3.77 -            cx_testing_allocator_add(data, ptr);
    3.78 -        }
    3.79 -        return ptr;
    3.80 -    }
    3.81 -}
    3.82 -
    3.83 -void *cx_calloc_testing(void *d, size_t nelem, size_t n) {
    3.84 -    cx_testing_allocator_s *data = d;
    3.85 -    void *ptr = calloc(nelem, n);
    3.86 -    data->alloc_total++;
    3.87 -    if (ptr == NULL) {
    3.88 -        data->alloc_failed++;
    3.89 -    } else {
    3.90 -        cx_testing_allocator_add(data, ptr);
    3.91 -    }
    3.92 -    return ptr;
    3.93 -}
    3.94 -
    3.95 -void cx_free_testing(void *d, void *mem) {
    3.96 -    cx_testing_allocator_s *data = d;
    3.97 -    data->free_total++;
    3.98 -    if (cx_testing_allocator_remove(data, mem)) {
    3.99 -        data->free_failed++;
   3.100 -        // do not even attempt to free mem, because it is likely to segfault
   3.101 -    } else {
   3.102 -        free(mem);
   3.103 -    }
   3.104 -}
   3.105 -
   3.106 -cx_allocator_class cx_testing_allocator_class = {
   3.107 -        cx_malloc_testing,
   3.108 -        cx_realloc_testing,
   3.109 -        cx_calloc_testing,
   3.110 -        cx_free_testing
   3.111 -};
   3.112 -
   3.113 -cx_testing_allocator_s cx_testing_allocator_data;
   3.114 -
   3.115 -struct cx_allocator_s cx_testing_allocator = {
   3.116 -        &cx_testing_allocator_class,
   3.117 -        &cx_testing_allocator_data
   3.118 -};
   3.119 -CxAllocator *cxTestingAllocator = &cx_testing_allocator;
   3.120 -
   3.121 -void cxTestingAllocatorReset(void) {
   3.122 -    memset(&cx_testing_allocator_data, 0, sizeof(cx_testing_allocator_s));
   3.123 -}
   3.124 -
   3.125 -bool cxTestingAllocatorVerify(void) {
   3.126 -    return cx_testing_allocator_data.live == 0
   3.127 -           && cx_testing_allocator_data.alloc_failed == 0 && cx_testing_allocator_data.free_failed == 0
   3.128 -           && cx_testing_allocator_data.alloc_total == cx_testing_allocator_data.free_total;
   3.129 -}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/util_allocator.cpp	Sat Apr 16 20:17:01 2022 +0200
     4.3 @@ -0,0 +1,161 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     4.8 + *
     4.9 + * Redistribution and use in source and binary forms, with or without
    4.10 + * modification, are permitted provided that the following conditions are met:
    4.11 + *
    4.12 + *   1. Redistributions of source code must retain the above copyright
    4.13 + *      notice, this list of conditions and the following disclaimer.
    4.14 + *
    4.15 + *   2. Redistributions in binary form must reproduce the above copyright
    4.16 + *      notice, this list of conditions and the following disclaimer in the
    4.17 + *      documentation and/or other materials provided with the distribution.
    4.18 + *
    4.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    4.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    4.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    4.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    4.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    4.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    4.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    4.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    4.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    4.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    4.29 + * POSSIBILITY OF SUCH DAMAGE.
    4.30 + */
    4.31 +
    4.32 +#include "util_allocator.h"
    4.33 +
    4.34 +void *cx_malloc_testing(void *d, size_t n) {
    4.35 +    auto data = reinterpret_cast<CxTestingAllocator *>(d);
    4.36 +    void *ptr = malloc(n);
    4.37 +    data->alloc_total++;
    4.38 +    if (ptr == nullptr) {
    4.39 +        data->alloc_failed++;
    4.40 +    } else {
    4.41 +        data->tracked.insert(ptr);
    4.42 +    }
    4.43 +    return ptr;
    4.44 +}
    4.45 +
    4.46 +void *cx_realloc_testing(void *d, void *mem, size_t n) {
    4.47 +    auto data = reinterpret_cast<CxTestingAllocator *>(d);
    4.48 +    void *ptr = realloc(mem, n);
    4.49 +    if (ptr == mem) {
    4.50 +        return ptr;
    4.51 +    } else {
    4.52 +        data->alloc_total++;
    4.53 +        if (ptr == nullptr) {
    4.54 +            data->alloc_failed++;
    4.55 +        } else {
    4.56 +            data->free_total++;
    4.57 +            if (data->tracked.erase(mem) == 0) {
    4.58 +                data->free_failed++;
    4.59 +            }
    4.60 +            data->tracked.insert(ptr);
    4.61 +        }
    4.62 +        return ptr;
    4.63 +    }
    4.64 +}
    4.65 +
    4.66 +void *cx_calloc_testing(void *d, size_t nelem, size_t n) {
    4.67 +    auto data = reinterpret_cast<CxTestingAllocator *>(d);
    4.68 +    void *ptr = calloc(nelem, n);
    4.69 +    data->alloc_total++;
    4.70 +    if (ptr == nullptr) {
    4.71 +        data->alloc_failed++;
    4.72 +    } else {
    4.73 +        data->tracked.insert(ptr);
    4.74 +    }
    4.75 +    return ptr;
    4.76 +}
    4.77 +
    4.78 +void cx_free_testing(void *d, void *mem) {
    4.79 +    auto data = reinterpret_cast<CxTestingAllocator *>(d);
    4.80 +    data->free_total++;
    4.81 +    if (data->tracked.erase(mem) == 0) {
    4.82 +        data->free_failed++;
    4.83 +        // do not even attempt to free mem, because it is likely to segfault
    4.84 +    } else {
    4.85 +        free(mem);
    4.86 +    }
    4.87 +}
    4.88 +
    4.89 +cx_allocator_class cx_testing_allocator_class = {
    4.90 +        cx_malloc_testing,
    4.91 +        cx_realloc_testing,
    4.92 +        cx_calloc_testing,
    4.93 +        cx_free_testing
    4.94 +};
    4.95 +
    4.96 +CxTestingAllocator::CxTestingAllocator() : CxAllocator() {
    4.97 +    cl = &cx_testing_allocator_class;
    4.98 +    data = this;
    4.99 +}
   4.100 +
   4.101 +bool CxTestingAllocator::verify() const {
   4.102 +    return tracked.empty() && alloc_failed == 0 && free_failed == 0 && alloc_total == free_total;
   4.103 +}
   4.104 +
   4.105 +// SELF-TEST
   4.106 +
   4.107 +#include <gtest/gtest.h>
   4.108 +
   4.109 +TEST(TestingAllocator, ExpectFree) {
   4.110 +    CxTestingAllocator allocator;
   4.111 +
   4.112 +    ASSERT_TRUE(allocator.verify());
   4.113 +    auto ptr = cxMalloc(&allocator, 16);
   4.114 +    ASSERT_NE(ptr, nullptr);
   4.115 +    EXPECT_FALSE(allocator.verify());
   4.116 +
   4.117 +    cxFree(&allocator, ptr);
   4.118 +    EXPECT_TRUE(allocator.verify());
   4.119 +}
   4.120 +
   4.121 +TEST(TestingAllocator, DetectDoubleFree) {
   4.122 +    CxTestingAllocator allocator;
   4.123 +
   4.124 +    ASSERT_TRUE(allocator.verify());
   4.125 +    auto ptr = cxMalloc(&allocator, 16);
   4.126 +    ASSERT_NE(ptr, nullptr);
   4.127 +
   4.128 +    cxFree(&allocator, ptr);
   4.129 +    EXPECT_TRUE(allocator.verify());
   4.130 +    ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
   4.131 +    EXPECT_FALSE(allocator.verify());
   4.132 +}
   4.133 +
   4.134 +TEST(TestingAllocator, FreeUntracked) {
   4.135 +    CxTestingAllocator allocator;
   4.136 +
   4.137 +    auto ptr = malloc(16);
   4.138 +    ASSERT_TRUE(allocator.verify());
   4.139 +    ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
   4.140 +    EXPECT_FALSE(allocator.verify());
   4.141 +    ASSERT_NO_FATAL_FAILURE(free(ptr));
   4.142 +}
   4.143 +
   4.144 +TEST(TestingAllocator, FullLifecycleWithRealloc) {
   4.145 +    CxTestingAllocator allocator;
   4.146 +    ASSERT_TRUE(allocator.verify());
   4.147 +    auto ptr = cxMalloc(&allocator, 16);
   4.148 +    ASSERT_NE(ptr, nullptr);
   4.149 +    EXPECT_EQ(allocator.tracked.size(), 1);
   4.150 +    ptr = cxRealloc(&allocator, ptr, 256);
   4.151 +    ASSERT_NE(ptr, nullptr);
   4.152 +    EXPECT_EQ(allocator.tracked.size(), 1);
   4.153 +    cxFree(&allocator, ptr);
   4.154 +    EXPECT_TRUE(allocator.verify());
   4.155 +}
   4.156 +
   4.157 +TEST(TestingAllocator, CallocInitializes) {
   4.158 +    CxTestingAllocator allocator;
   4.159 +    const char* zeros[16] = {0};
   4.160 +    auto ptr = cxCalloc(&allocator, 16, 1);
   4.161 +    EXPECT_EQ(memcmp(ptr, zeros, 16), 0);
   4.162 +    cxFree(&allocator, ptr);
   4.163 +    EXPECT_TRUE(allocator.verify());
   4.164 +}
     5.1 --- a/test/util_allocator.h	Sat Apr 16 18:02:10 2022 +0200
     5.2 +++ b/test/util_allocator.h	Sat Apr 16 20:17:01 2022 +0200
     5.3 @@ -31,60 +31,44 @@
     5.4  
     5.5  #include "cx/allocator.h"
     5.6  
     5.7 -#ifdef __cplusplus
     5.8 -extern "C" {
     5.9 -#endif
    5.10 +#include <set>
    5.11  
    5.12 -#define CX_TESTING_ALLOCATOR_MAX_LIVE 1024
    5.13 -
    5.14 -typedef struct {
    5.15 +struct CxTestingAllocator : public CxAllocator {
    5.16      /**
    5.17       * Total number of all allocations (malloc, calloc, realloc).
    5.18       * A realloc() does only count when the memory has to be moved.
    5.19       */
    5.20 -    int alloc_total;
    5.21 +    unsigned alloc_total = 0;
    5.22      /**
    5.23       * Number of failed allocations (malloc, calloc, realloc).
    5.24       */
    5.25 -    int alloc_failed;
    5.26 +    unsigned alloc_failed = 0;
    5.27      /**
    5.28       * Total number of freed pointers.
    5.29       * A reallocation also counts as a free when the memory has to be moved.
    5.30       */
    5.31 -    int free_total;
    5.32 +    unsigned free_total = 0;
    5.33      /**
    5.34       * Number of failed free invocations.
    5.35       * A free() is considered failed, if it has not been performed on tracked memory.
    5.36       */
    5.37 -    int free_failed;
    5.38 +    unsigned free_failed = 0;
    5.39      /**
    5.40 -     * Number of memory blocks that are currently live (and tracked).
    5.41 -     * The maximum number of tracked blocks is defined in #CX_TESTING_ALLOCATOR_MAX_LIVE.
    5.42 +     * The set of tracked memory blocks.
    5.43       */
    5.44 -    int live;
    5.45 +    std::set<void *> tracked;
    5.46 +
    5.47      /**
    5.48 -     * The array of tracked memory blocks.
    5.49 +     * Constructs a new testing allocator.
    5.50       */
    5.51 -    void *tracked[CX_TESTING_ALLOCATOR_MAX_LIVE];
    5.52 -} cx_testing_allocator_s;
    5.53 +    CxTestingAllocator();
    5.54  
    5.55 -extern CxAllocator *cxTestingAllocator;
    5.56 -
    5.57 -/**
    5.58 - * Resets the testing allocator information.
    5.59 - * This function SHOULD be called prior to any use of this allocator.
    5.60 - */
    5.61 -void cxTestingAllocatorReset(void);
    5.62 -
    5.63 -/**
    5.64 - * Checks whether all allocated memory is properly freed and no failed (de)allocations happened.
    5.65 - *
    5.66 - * @return true on success, false if there was any problem
    5.67 - */
    5.68 -bool cxTestingAllocatorVerify(void);
    5.69 -
    5.70 -#ifdef __cplusplus
    5.71 -}; /* extern "C" */
    5.72 -#endif
    5.73 +    /**
    5.74 +     * Verifies that all allocated memory blocks are freed and no free occurred twice.
    5.75 +     *
    5.76 +     * @return true iff all tracked allocations / deallocations were valid
    5.77 +     */
    5.78 +    bool verify() const;
    5.79 +};
    5.80  
    5.81  #endif /* UCX_UTIL_ALLOCATOR_H */

mercurial